Как избежать ошибки «grep: Argument list too long»?

7

Я использую Mac 10.7.5 и на оболочке Bash. Я пытаюсь найти экземпляры строки в группе файлов, но получаю эту ошибку

Daves-MacBook-Pro:folder davea$ find . -name "*" | xargs grep 'state-icons'
xargs: grep: Argument list too long

Как я могу запустить команду (или аналогичную), чтобы избежать этой ошибки?

Дейв
источник
grep '...' <( find … )может быть?
slhck

Ответы:

7

Вы можете использовать -nопцию xargsограничения количества аргументов.

find . -name "*" | xargs -n 20 grep 'state-icons'

Обратите внимание, что это не работает для файлов с пробелами в их именах.

choroba
источник
3
Это работает для файлов с пробелами в их именах. Сбой только для файлов с символами новой строки в их именах, которые намного реже.
Ричи
Может ли ограничение количества аргументов помешать отображению правильных результатов? В конечном счете, моя цель - найти файлы с экземпляром нужной строки, а не просто устранить сообщение об ошибке.
Дейв
@Dave: Нет, grepбудет запущен несколько раз, по 20 файловых аргументов каждый. Вы можете добавить, -type fчтобы findизбежать ошибок при grepпопытке открыть каталоги.
Чороба
2
Существует риск, что если findотчеты, скажем, 61 файл, то xargsбудут выполняться grepчетыре раза - три раза с 20 файлами и один раз с 1 файлом. Когда grepзапускается с несколькими файлами, он сообщает имена файлов, в которых он находит совпадения; не так только с одним аргументом имени файла. Уловка, которая обычно используется для исправления этого xargs -n 20 grep 'state-icons' /dev/null, так сказать , xargsбудет запускаться grepтри раза с 21 файлом и один раз с 2 файлами - конечно /dev/null, это будет дополнительный файл , который в противном случае не будет влиять на запуск.
Скотт
2
@Scott: Вы также можете использовать -Hопцию grep(если поддерживается).
Чороба
-2

Как насчет этого, если вы хотите искать через имя файла :

for x in ./**/*.*; do echo "$x" | grep 'state-icons' ; done

и это, если вы хотите просмотреть содержимое файла :

for x in ./**/*.*; do grep 'state-icons' "$x" ; done
youkaichao
источник
1
Это будет работать grepтолько с именами файлов , а не с их содержимым. Также *.*не означает «все файлы» (как в Windows); он ограничивает поиск файлами, которые имеют .в своем имени.
Скотт
@ Скотт, но -nameаргумент указывает, что они хотят искать имя файла. Если они хотят искать содержимое файла, просто опустите echoи используйтеgrep 'state-icons' $x
youkaichao
Пожалуйста, отредактируйте свой ответ, чтобы включить этот вариант. Ох, и я почти забыл: пожалуйста, укажите ваши переменные.
Скотт