У меня есть структура каталогов, которая выглядит так:

main_directory/
    directory1:
        sub_directory1:
            files:
                myfile.txt
                otherfile.txt
        sub_directory2:
            files:
                myfile.txt
                otherfile.txt
        sub_directory3:
            files:
                myfile.txt
                otherfile.txt
        sub_directory4:
            files:
                myfile.txt
                otherfile.txt
    directory2:
        sub_directory1:
            files:
                myfile.txt
                otherfile.txt
        sub_directory2:
            files:
                myfile.txt
                otherfile.txt
        sub_directory3:
            files:
                myfile.txt
                otherfile.txt
        sub_directory4:
            files:
                myfile.txt
                otherfile.txt

Я пытаюсь выяснить (методом проб и ошибок, потому что я не эксперт в Linux), как сжимать только файлы myfile.txt во всех каталогах. Поскольку все они имеют одно и то же имя файла и разные пути (обойти это было невозможно), мне также нужно сохранить путь к файлам в архиве. Итак, окончательный архивный файл tar, который я хочу создать, будет иметь следующее содержимое:

mytar.tar.gz
    main_directory/directory1/sub_directory1/files/myfile.txt
    main_directory/directory1/sub_directory2/files/myfile.txt
    main_directory/directory1/sub_directory3/files/myfile.txt
    main_directory/directory1/sub_directory4/files/myfile.txt
    main_directory/directory2/sub_directory1/files/myfile.txt
    main_directory/directory3/sub_directory2/files/myfile.txt
    main_directory/directory4/sub_directory3/files/myfile.txt
    main_directory/directory5/sub_directory4/files/myfile.txt

Есть ли простой способ bash сделать это? Полагаю, я мог бы написать для этого сценарий python, но это кажется излишним.

Есть ли у кого-нибудь совет?

4
Brett 24 Авг 2014 в 07:32

4 ответа

Лучший ответ

Это преодолело эту проблему, описанную в другом ответе.

find main_directory/ -name "myfile.txt" | tar -czvf mytar.tar.gz -T -
4
Brett 24 Авг 2014 в 05:02

Предполагая, что файлов не так много, вы можете сделать что-то вроде:

cd main_directory/..
find main_directory -name "myfile.txt" | xargs tar zcf mytar.tar.gz

Если файлов много, вы можете передать список файлов в файл / поток и передать его в tar.

find main_directory -name "myfile.txt" -print0 | tar zcf myar.tar.gz --null -T -

Это распечатывает имена файлов, разделенные нулями (от -print0 до find), и инструктирует tar правильно проанализировать это из stdin; использование нулей гарантирует, что любые специальные символы в каталогах обрабатываются правильно

2
Emil Sit 25 Авг 2014 в 10:34

С достаточно новой (я полагаю, 4.0.0+) версией bash (и ряда других оболочек) будет работать следующее:

tar -czf mytar.tar.gz main_directory/**/myfile.txt
0
Etan Reisner 24 Авг 2014 в 04:01

Если структура каталогов действительно такая регулярная, подстановочный знак

main_directory/*/*/files/myfile.txt

Будет соответствовать нужным файлам. Однако, если файлов много, вам может потребоваться вернуться к find / xargs, чтобы избежать проблемы "слишком длинный список аргументов" (ARG_MAX).

Если есть файлы с именем myfile.txt, которые вы не хотите включать, потому что их путь не соответствует в точности подстановочному знаку, безусловно, есть способы исключить их и из find; возможно, тогда это дополнительное ограничение следует указать в вопросе.

0
tripleee 25 Авг 2014 в 10:44