2009-03-27 3 views
3

У меня есть файл, который содержит имена файлов (и полный путь к ним), и я хочу найти слово во всех них. некоторые псевдо-код, чтобы объяснить:Использовать строки в файле как имена файлов для grep?

grep keyword <all files specified in files.txt> 

или

cat files.txt > grep keyword 
cat files txt | grep keyword 

проблема заключается в том, что я могу получить только Grep для поиска имен файлов, а не содержание фактических файлов.

ответ

7
cat files.txt | xargs grep keyword 

или

grep keyword `cat files.txt` 

или (что эквивалентно предыдущей, но труднее MIS-прочитанных)

grep keyword $(cat files.txt) 

должен сделать трюк.

Ловушки:

  • Если files.txt содержит имена файлов с пробелами, либо решение будет работать неправильно, потому что «Это filename.txt» будет интерпретироваться как четыре файла, «Это», «is», «a» и «filename.txt». Хорошая причина, почему у вас не должно быть пробелов в ваших именах.

    • Есть способы обойти это, но ни один из них не является тривиальным. (Найти ... -print0/xargs -0 это один из них.)
  • Второй (кот) версия может привести к очень длинной командной строки (что может произойти сбой при превышении пределов среды) , Первая (xargs) версия обрабатывает длинный ввод автоматически; xargs предлагает несколько опций для управления деталями.

+0

xargs не будет генерировать отдельный процесс для каждой строки, которую он читает со стандартного ввода. xargs вызовет grep с максимально возможным количеством аргументов (скажем, ARG_MAX). Количество вызовов grep будет равно ceil (num_files/ARG_MAX). – sigjuice

+0

Правильно ... Я неправильно прочитал справочную страницу xargs в этом отношении. Ред. (Фактические пределы xargs могут быть определены с помощью «xargs --show-limits». – DevSolar

-2

Долгое время, когда последний создавал скрипт оболочки bash, но вы могли сохранить результат первого grep (тот, который нашел все имена файлов) в массиве и перебрать его, выдав еще больше команд grep.

Хорошей отправной точкой должно стать руководство по настройке bash.

2

Оба ответы от DevSolar работы (протестировано на Linux Ubuntu), но версия xargs является предпочтительным, если может быть много файлов, так как это позволит избежать запуска в пределах длины строки команды.

так:

cat files.txt | xargs grep keyword 

это путь

+0

xargs не порождает новый процесс для каждого аргумента – pixelbeat

+0

Вы выиграли премию «Бесполезное использование кота». :-) http: // partmaps .org/era/unix/award.html – sigjuice

2
tr '\n' '\0' <files.txt | LANG=C xargs -r0 grep -F keyword 
  • тр будет разграничить имена с NUL характером, так что пространства не имеет существенного значения (отметьте соответствующую опцию -0 к xargs).
  • xargs -r запустит один процесс grep для «большого» количества файлов, но не запускает какой-либо grep-процесс, если нет файлов.
  • LANG = C означает использование быстрых процедур для согласования, а не медленно локали те
  • GREP -F означает использовать быструю строку соответствия, а не медленное регулярного выражения соответствия
+0

Не сбивается ли LANG = C, если имена файлов не ASCII-7? – DevSolar

+0

Не для фиксированных строк нет. Если вы не хотите греться для таких вещей, как «[: upper:]», тогда да. – pixelbeat

0

bash, ksh & zsh версии:

grep keyword $(<files.txt) 
Смежные вопросы