Как может я рекурсивно zip-файлы в их собственной папке?

У меня есть следующая структура каталогов:

/Data
 - file 1
 - file 2

  /Folder1

   - file 3
   - file 4

  /Folder2
   - file 5
   - file 6

    /Folder3
      - file 7
      - file 8

В Linux я хочу к zip-файлам (исключая папки) в каждом каталоге и создаю 7z (или zip) архив в каждой папке, заканчивающейся следующее:

/Data
     Data.7z (Note: this should contain only file1 & 2, not any sub directories)

      /Folder1

       Folder1.7z (this should contain only file3 & 4, not any sub directories)

      /Folder2
       Folder2.7z (this should contain only file5 & 6, no Folder3)

        /Folder3
          Folder3.7z (should contain only file7 & 8)

Следующий сценарий работает в первом каталоге, но не в подкаталогах:

for i in */ ; do base=$(basename “$i”) ; cd $base ; 7za a -t7z -r $base * ; .. ; cd .. ; done;

Как я могу достигнуть этого?

1
задан 13 February 2018 в 02:52

2 ответа

Если Вы хотите использовать 7z, хитрая часть, кажется, убеждает это не рекурсивно вызвать; документация указала -r- переключатель, кажется, нефункционален, и предложенное обходное решение от автора программного обеспечения должно исключить подкаталоги с выражением с подстановочными знаками -x!*/

Так, данный

$ tree Data
Data
├── file1
├── file2
├── Folder1
│  ├── file3
│  └── file4
├── Folder2
│  ├── file5
│  └── file6
└── Folder3
    ├── file7
    └── file8

3 directories, 8 files

затем

find Data -type d -execdir sh -c 'cd "$1" && 7z a "$1".7z -x!*/ && cd -' sh {} \;

результаты в

$ tree Data
Data
├── Data.7z
├── file1
├── file2
├── Folder1
│  ├── file3
│  ├── file4
│  └── Folder1.7z
├── Folder2
│  ├── file5
│  ├── file6
│  └── Folder2.7z
└── Folder3
    ├── file7
    ├── file8
    └── Folder3.7z

3 directories, 12 files

где, например, мы можем проверить это Folder2.7z содержит только использование файлов его собственной папки

$ 7z l Data/Folder2/Folder2.7z 

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_CA.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM)2 Duo CPU     P9600  @ 2.53GHz (1067A),ASM)

Scanning the drive for archives:
1 file, 128 bytes (1 KiB)

Listing archive: Data/Folder2/Folder2.7z

--
Path = Data/Folder2/Folder2.7z
Type = 7z
Physical Size = 128
Headers Size = 128
Solid = -
Blocks = 0

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2018-02-12 18:37:37 ....A            0            0  file5
2018-02-12 18:37:37 ....A            0            0  file6
------------------- ----- ------------ ------------  ------------------------
2018-02-12 18:37:37                  0            0  2 files

Примечание: !*/ может потребовать дополнительного выхода в средах (таких как интерактивная оболочка удара) где ! оператор расширения истории.

3
ответ дан 7 December 2019 в 12:30

Это непроверенный код, используемый только с «echo», так как я не люблю заканчивать несколькими zip-файлами. И это синтаксис phantasy zip, так как я не знаю 7za, но я объясню:

find . -type d -execdir /.../ad-hoc.sh {} ";"

Сценарий ad-hoc.sh должен иметь абсолютный путь и не должен находиться в текущий путь, чтобы не повлиять на результат, но он может быть в родительском каталоге:

find . -type d -execdir $PWD/../ad-hoc.sh {} ";"

и, если он не выполнен исполняемым, будет явно вызван:

find . -type d -execdir bash $PWD/../ad-hoc.sh {} ";"

Find должен искать в текущий dir, только для файлов типа d (dirs), где -exexete bashscript с параметром {}, найденный каталог.

Хорошо - что за ad-hoc.sh мы выполняем в dir и subdirs? Это еще одна находка:

#!/bin/bash
dir=$1
find $dir -maxdepth 1 -type f -exec echo zip -o "$dir.zip" {} +

-maxdepth 1 запрещает поиск для поиска по подкаталогам, -type говорит, что просто работает с файлами. -exec запускает команду для проверки «echo zip ...», но если она выглядит многообещающе (вы часто делаете резервные копии, не так ли?), вы - ну, вот мой псевдокод: -o: = -output «$ PWD.zip», а {} + - список файлов.

tree
.
├── buch-klein.kry
├── buch.kry
├── crypt
│   ├── moveto.sh.crypt
│   └── sub1
│       ├── foo.crypt
│       └── sub2
│           └── bar.crypt
├── original
│   ├── 1
│   │   └── 2
│   │       └── 3
│   ├── moveto.sh
│   └── sub1
│       └── sub2
│           └── up3 -> ../../../nr
├── outputfile.txt
├── rot.sh
└── zoom.sh

find . -type d -execdir $PWD/../ad-hoc.sh {} ";" 
zip -o ./..zip ././buch-klein.kry ././rot.sh ././buch.kry ././zoom.sh ././outputfile.txt
zip -o ./original.zip ./original/moveto.sh
zip -o ./crypt.zip ./crypt/moveto.sh.crypt
zip -o ./sub1.zip ./sub1/foo.crypt
zip -o ./sub2.zip ./sub2/bar.crypt

Каждый файл с расширением является обычным файлом, и каждый файл без является каталогом или символической ссылкой на каталог (up3).

{} должен быть последним элементом команды find -exec перед завершающей ";" или +, поэтому вы должны построить свою 7z-команду соответственно.

, поэтому, если ваша команда 7za -

      7za a -t7z -r $dir.7za *

, ad-hoc.sh может выглядеть так:

#!/bin/bash
dir=$1
find $dir -maxdepth 1 -type f -exec echo 7za -t7z -r "$dir.7za" {} +
0
ответ дан 7 December 2019 в 12:30

Другие вопросы по тегам:

Похожие вопросы: