Как я могу обрабатывать пробелы в именах файлов при использовании xargs в результатах поиска?

28

Одна из моих общих практик - выполнять greps для всех файлов определенного типа, например, находить все файлы HTML, в которых есть слово «rumpus». Для этого я использую

find /path/to -name "*.html" | xargs grep -l "rumpus"

Иногда findвозвращает файл с пробелом в имени, например my new file.html. Когда я xargsпередал это grep, я получаю эти ошибки:

grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory

Я могу видеть, что здесь происходит: или канал, или xargsтрактует пространства как разделители между файлами. Впрочем, я не могу понять, как предотвратить такое поведение. Можно ли это сделать с помощью find+ xargs? Или я должен использовать совершенно другую команду?

abeger
источник

Ответы:

29

использование

find ... -print0 | xargs -0 ...

например

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"

со страницы поиска

-print0
          True; print the full file name on the standard  output,  followed
          by  a  null  character  (instead  of  the  newline character that
          ‘-print’ uses).  This allows file names that contain newlines  or
          other  types  of  white space to be correctly interpreted by pro-
          grams that process the find output.  This option  corresponds  to
          the ‘-0’ option of xargs.
user9517 поддерживает GoFundMonica
источник
15

Вам не нужно использовать xargs , потому что find может выполнять команды самостоятельно. При этом вам не нужно беспокоиться о интерпретации символов оболочки в имени.

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +

со страницы поиска

-exec command {} +
Этот вариант действия -exec запускает указанную команду для выбранных файлов, но командная строка создается путем добавления каждого выбранного имени файла в конце; общее количество вызовов команды будет намного меньше, чем количество совпавших файлов. Командная строка строится почти так же, как xargs создает свои командные строки. Только один экземпляр `{} 'разрешен в команде. Команда выполняется в начальном каталоге.

Sciurus
источник
Я бы проголосовал за это, но я не ушел на сегодня - я сделаю это завтра.
user9517 поддерживает GoFundMonica
1
@Iain - поехали (согласен, кстати).
Эдуардо Иванец
Просто используя find вы все еще упускаете возможности xargs, плюс вам приходится иметь дело с глупыми правилами цитирования. Посмотрите аргумент -P для xargs, если у вас более одного ядра / процессора.
Slartibartfast
8

Если версии find и xarg в вашей системе не поддерживают -print0и не -0переключаются (например, AIX find и xargs), вы можете использовать это:

find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"

Здесь sed позаботится о том, чтобы избежать пространства для xargs.

Ян Птачник
источник
Это помогло мне, потому что у меня был длинный список имен файлов, которые было трудно создать, который я использовал несколько раз. Я не могу просто пройти findих все снова.
Скотт М.