
У меня следующая структура каталогов:
test/
test/1/
test/foo2bar/
test/3/
Я хочу сжать каталог "test", исключив все, что находится в подкаталогах (глубина не предопределена), которые включают строки "1" или "2". В оболочке bash я хочу использоватьнаходитьи передать его выводсмола. Я сначала тестируюнаходить:
find test/ -not -path "*1*" -not -path "*2*"
Выход:
test/
test/3
Отлично. Поэтому я объединяю это ссмола:
find test/ -not -path "*1*" -not -path "*2*" | tar -czvf test.tar.gz --files-from -
Выход:
test/
test/3/
test/1/
test/foo2bar/
test/3/
Действительно, в архиве присутствуют и «test/1», и «test/foo2bar».Почему эти аргументы были переданы tar, если они не должны были присутствовать в выводе find?
решение1
Чтобы расширить то, что сказал @cuonglm, tar
по умолчанию работает рекурсивно. Если вы передадите ему имя каталога, он заархивируетсодержаниеэтого каталога.
Вы можете изменить find
команду так, чтобы она возвращала только имена файлов, а не каталогов...
find test/ -type f -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --files-from -
Вместо этого вы можете использовать --no-recursion
флаг для tar
:
find test/ -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --no-recursion --files-from -
Что приводит к:
test/
test/3/
Флаг --no-recursion
специфичен для GNU tar. Если вы используете что-то другое, обратитесь к соответствующей странице руководства, чтобы узнать, доступна ли похожая функция.
Обратите внимание, что ваша find
команда исключитфайлыкоторые содержат 1
или 2
в пути, а также в каталогах.
решение2
С помощью GNU tar вы также можете использовать --exclude
опцию исключения файлов по именам.
$ tar --exclude "*1*" --exclude "*2*" -cvf foo.tar test/
test/
test/3/
Также есть -X
или --exclude-from
, который берет файл, из которого считываются шаблоны исключений.
Хотя find -not -path "*1*"
, это также исключит файлы, имена которых содержат 1
или 2
. Чтобы пропустить толькокаталогичьи имена соответствуют шаблону, используйте find -prune
и tar --no-recursion
:
$ touch test/3/blah.1
$ find test/ -type d \( -name "*1*" -o -name "*2*" \) -prune -o -print |
tar cvf test.tar --files-from - --no-recursion
test/
test/3/
test/3/blah.1
(По крайней мере, GNU tar и FreeBSD tar имеют --no-recursion
)