17

Я пытаюсь создать скрипт, который может сжимать файлы с определенным расширением в нескольких каталогах в один tar-шар. В настоящее время у меня есть в файле сценария:

find "$rootDir" -name '*doc' -exec tar rvf docs.tar {} \;

Где $rootDir - базовый путь для поиска.

Это нормально, за исключением того, что пути в файле tar являются абсолютными. Я бы предпочел, чтобы пути были относительно $rootDir . Как бы я поступил так?

Пример текущего tar -tf docs.tar где $rootDir - это /home/username/test output:

home/username/test/subdir/test.doc
home/username/test/second.doc

Что я хочу, чтобы результат был:

./subdir/test.doc
./second.doc

2 ответа2

11

Если вы запустите find из нужного корневого каталога и не укажете абсолютную начальную точку в параметрах find , он выведет относительные пути к вызовам команды tar он создает. Вот так:

cd $rootDir
find . -name '*doc' -exec tar rvf docs.tar {} \;

Если вы не хотите постоянно менять текущий рабочий каталог и используете bash или аналогичный в качестве оболочки, вы можете сделать это.

pushd $rootDir
find . -name '*doc' -exec tar rvf docs.tar {} \;
popd

вместо.

Обратите внимание, что pushd/popd присутствуют не во всех оболочках, поэтому проверьте соответствующую страницу руководства. Они присутствуют в bash, но не в базовой реализации sh, поэтому, явно используя /bin/bash вы можете положиться на них, но не сможете, если вместо этого скрипт запросит /bin/sh (так как это может отобразить меньшую оболочку, которая не нет улучшений bash)

1

Вы можете использовать формат %P в директиве -printf :

find ${rootDir} -name '*.doc' -printf "%P\n"

будет отображаться в вашем примере:

subdir/test.doc
second.doc

Затем вы можете использовать этот список find в выражении for для запуска нашей команды exec, например:

for f in $( find ${rootDir} -name '*.doc' -printf "%P\n" );
do
    tar rvf docs.tar ${f}
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .