Як я можу обробляти пробіли в іменах файлів при використанні 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? Або я повинен використовувати зовсім іншу команду?

Відповіді:


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.

15

Не потрібно використовувати xargs , оскільки find може виконувати команди самостійно. Роблячи це, вам не доведеться турбуватися про інтерпретацію символів оболонки в імені.

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

зі сторінки пошуку чоловіка

Команда -exec {} +
Цей варіант дії -exec виконує вказану команду для вибраних файлів, але командний рядок будується додаванням кожного вибраного імені файлу в кінці; загальна кількість викликів команди буде значно меншою, ніж кількість відповідних файлів. Командний рядок побудований приблизно так само, як xargs будує свої командні рядки. У команді дозволений лише один екземпляр `{}. Команда виконується в початковому каталозі.


Я б підтримав це, але у мене сьогодні не залишилося - я це зроблю завтра.
user9517 підтримує GoFundMonica

1
@Iain - там ти їдеш (я згоден, до речі).
Едуардо Іванець

Просто використовуючи функцію пошуку, ви все ще пропускаєте функції xargs, плюс вам доведеться мати справу з дурними правилами цитування. Дивіться аргумент -P для xargs, якщо у вас є більше одного ядра / процесора.
Slartibartfast

8

Якщо версії find and xarg у вашій системі не підтримують -print0і -0перемикачі (наприклад, AIX find та xargs), ви можете скористатися цим:

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

Тут sed дбатиме про те, щоб уникнути місця для xargs.


Це допомогло мені, оскільки у мене був довгий список імен файлів, які складно було створити, які я використовував кілька разів. Я не можу просто findповторити їх знову.
Скотт М.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.