Рассматривать каждый случай по очереди:
xargs
Эта программа добавляет каждую строку из ввода в качестве параметра к любой команде, переданной в качестве своего собственного параметра, а затем запускает результирующую команду, поэтому, если команда find
перечисляет три файла a
, b
и c
в текущем каталоге, она выдаст их в качестве вывода :
./a
./b
./c
Если это передано в xargs rm
, то эта команда будет выполнена:
rm ./a ./b ./c
Однако, если find
также находит файл с именем " d e "
, то выполненная команда становится:
rm ./a ./b ./c ./ d e
Чтобы справиться с этим, find
предоставляет опцию -print0
, которая добавляет нулевой символ (\0
) после каждого файла вместо обычной новой строки. Чтобы сообщить xargs
что входные данные находятся в этой форме, добавьте параметр -0
, поэтому введите команду:
find . ... -print0|xargs -0 rm
соберет и выполнит команду:
rm "./a" "./b" ."/c" "./ d e "
Это будет работать со всеми именами файлов, включая имена, содержащие пробелы, табуляции и новые строки.
find -exec
Когда вызывается эта опция, то для каждого найденного файла выполняется то, что следует (до \;
). Это не очень полезно, если только нет средств для ссылки на найденный в данный момент файл, и именно это и делает {}
. Его можно вызывать более одного раза в строке выполнения, например, для копирования выбранных файлов в каталог резервного копирования:
find . ... -exec cp "{}" "/BackUp/{}" \;
Это в приведенном выше примере find
будет выполняться по очереди:
cp "./a" "/BackUp/./a"
cp "./b" "/BackUp/./b"
cp "./c" "/BackUp/./c"
Обратите внимание, что вне использования в команде find
, {
и }
имеют специальные значения в bash (несколько команд и раскрывающиеся списки), но они включают другие символы в скобках: строка {}
копируется буквально, поэтому не требует экранирования.