Я пытаюсь запустить grep для списка из нескольких сотен файлов:
$ head -n 3 <(cat files.txt)
admin.php
ajax/accept.php
ajax/add_note.php
Однако, несмотря на то, что я искал строку, которая, как мне известно, находится в файлах, следующее не ищет файлы:
$ grep -i 'foo' <(cat files.txt)
$ grep -i 'foo' admin.php
The foo was found
Я знаком с -f
флагом, который будет читать шаблоны из файла. Но как читать входные файлы ?
Я рассмотрел ужасный обходной путь копирования файлов во временный каталог, который, cp
кажется, поддерживает <(cat files.txt)
формат, и оттуда копировал файлы. Ширли, есть лучший способ.
источник
while
смог получить строки file.txt как таковые.while
не совсем получает строки из файла,read
делает это;while
просто позволяет нам сделать это в цикле. Цикл заканчивается, когда происходитread
сбой (т. Е. Возвращает ненулевой код возврата), обычно из-за достижения конца файла.IFS= read -r filename
,read filename
это что-то еще.-H
это расширение GNU. Вы скучаете по некоторым--
.при условии, что файлы пустые или разделены символом новой строки (где кавычки или обратные слэши могут использоваться для экранирования этих разделителей). В GNU
xargs
вы можете указать разделитель с помощью-d
(который затем отключает обработку цитирования).при условии, что файлы разделены пробелом, символом табуляции или новой строки (нет возможности избежать их, хотя вы можете выбрать другой разделитель, назначив его
IFS
). Это не удастся, если список файлов слишком большой на большинстве систем.Они также предполагают, что ни один из файлов не вызывается
-
.источник
$(< file)
вместо$(cat file)
, по крайней мере вbash
иzsh
.Чтобы прочитать список имен файлов из stdin вы можете использовать
xargs
. Например,По умолчанию
xargs
считывает элементы из стандартного ввода, разделенные пробелами. Он-d'\n'
говорит ему использовать символ новой строки в качестве разделителя аргументов, чтобы он мог обрабатывать имена файлов, содержащие пробелы. (Как указывает Стефан Шазелас, это расширение GNU). Тем не менее, он не справится с именами файлов, содержащих переводы строк; нам понадобится немного более сложный подход, чтобы справиться с этим.FWIW, этот подход несколько быстрее, чем
while read
цикл, так какread
команда bash очень медленная - она читает свои данные символ за символом, тогда какxargs
считывает ввод более эффективно. Кроме того, командаxargs
вызывается толькоgrep
столько раз, сколько необходимо, при этом каждый вызов получает несколько имен файлов, и это более эффективно, чемgrep
индивидуальный вызов для каждого имени файла.Для получения дополнительной информации см. Справочную страницу xargs и информационную страницу xargs.
источник
xargs
можете читать элементы из файла (например, из вашегоfiles.txt
списка) с помощью этой опции:Так что это тоже должно работать:
или для пробелов в именах файлов
источник
Вы также можете сделать для, но пример Ориона является самым простым:
(Для каждого файла, указанного в файле files.txt, выполните для него команду grep.)
источник