Что делает “xargs grep”, делают?

Я знаю grep команда и я узнаем о технических возможностях xargs, таким образом, я прочитал эту страницу, которая дает некоторые примеры того, как использовать xargs команда.

Я смущен последним примером, пример 10. Это говорит, что "Команда xargs выполняет команду grep для нахождения всех файлов (среди файлов, обеспеченных командой находки), который содержал строку ‘stdlib.h’"

$ find . -name '*.c' | xargs grep 'stdlib.h'
./tgsthreads.c:#include
./valgrind.c:#include
./direntry.c:#include
./xvirus.c:#include
./temp.c:#include
...
...
...

Однако, что различие к простому использованию

$ find . -name '*.c' | grep 'stdlib.h'

?

Очевидно, я все еще борюсь с тем, что точно делает xargs, таким образом, любая справка ценится!

25
задан 4 October 2016 в 16:27

4 ответа

$ find . -name '*.c' | grep 'stdlib.h'

Это передает вывод по каналу (stdout) * от find к (stdin) * grep 'stdlib.h' как текст (т.е. имена файлов рассматриваются как текст). grep делает его обычную вещь и находит согласующие отрезки длинной линии в этом тексте (любые имена файлов, которые сами содержат шаблон). Содержание файлов никогда не читается.

$ find . -name '*.c' | xargs grep 'stdlib.h'

Это создает команду grep 'stdlib.h' к которому каждый результат find аргумент - таким образом, это будет искать соответствия в каждом файле, найденном find (xargs может считаться превращением его stdin в аргументы данным командам), *

Использовать -type f в Вашей команде находки, или Вы получите ошибки от grep для соответствия каталогам. Кроме того, если имена файлов имеют пробелы, xargs завинтит плохо, так используйте пустой разделитель путем добавления -print0 и xargs -0 для более надежных результатов:

find . -type f -name '*.c' -print0 | xargs -0 grep 'stdlib.h'

*добавили эти дополнительные объяснительные точки, как предложено в комментарии @cat

30
ответ дан 23 November 2019 в 01:12

xargs привык к автоматическому, генерируют параметры командной строки, базирующиеся (обычно) на списке файлов.

Настолько рассматривающий некоторые альтернативы использованию команды followoing xargs:

find . -name '*.c' -print0 | xargs -0 grep 'stdlib.h'

существует несколько причин использовать его вместо других опций, которые не были первоначально упомянуты в других ответах:

  1. find . -name '*.c' -exec grep 'stdlib.h' {}\; генерирует один grep процесс для каждого file—, это обычно считают плохой практикой и может создать большую нагрузку для системы, если существует много найденных файлов.
  2. , Если существует много файлов, grep 'stdlib.h' $(find . -name '*.c'), команда, вероятно, перестанет работать, потому что вывод $(...) операция превысит максимальную длину командной строки оболочки

, Как упомянуто в других ответах, причине использования -print0 аргумент find в этом сценарии и -0 аргумент xargs, то, так, чтобы имена файлов с определенными символами (например, кавычки, пробелы или даже новые строки) были все еще обработаны правильно.

4
ответ дан 23 November 2019 в 01:12

xargs берет свой стандартный вход и превращает его в командную строку args.

find . -name '*.c' | xargs grep 'stdlib.h' очень похоже на

grep 'stdlib.h' $(find . -name '*.c')  # UNSAFE, DON'T USE

И даст те же результаты, пока список имен файлов не является слишком длинным для единственной командной строки. (Linux поддерживает мегабайты текста на единственной командной строке, так обычно Вам не нужен xargs.)


Но оба из них сосут, потому что они повреждаются, если Ваши имена файлов содержат пробелы. Вместо этого find -print0 | xargs -0 работы, но так делает

find . -name '*.c' -exec grep 'stdlib.h' {} +

Это никогда не передает имена файлов по каналу нигде: find обрабатывает их в пакетном режиме в большую командную строку и выполнения grep непосредственно.

\; вместо + выполнения grep отдельно для каждого файла, который намного медленнее. Не делайте этого. Но + расширение GNU, таким образом, Вам нужно xargs чтобы сделать это эффективно, если Вы не можете принять, GNU находит.


Если Вы не учитываете xargs, find | grep делает его сопоставление с образцом против списка имен файлов это find печать.

Таким образом в той точке, Вы могли бы также просто сделать find -name stdlib.h. Конечно, с -name '*.c' -name stdlib.h, Вы не получите вывода, потому что те шаблоны не могут и соответствовать, и поведение находки по умолчанию к И правила вместе.

Замена less в любой точке в процессе для наблюдения то, что производит любую часть конвейера, производит.


Дальнейшее чтение: http://mywiki.wooledge.org/BashFAQ имеет некоторый большой материал.

6
ответ дан 23 November 2019 в 01:12

В целом, xargs используется для случаев, где Вы передали бы по каналу (с символом |) что-то от одной команды до другого (Command1 | Command2), но вывод от первой команды правильно не получен как вход для второй команды.

Это обычно происходит, когда вторая команда не обрабатывает ввод данных через Стандарт В (stdin) правильно (например: Несколько строк, как введено, путь строки являются установкой, символы, используемые в качестве входа, несколько параметров, как введено, тип данных, полученный, как введено, и т.д.). Чтобы дать Вам быстрый пример, протестируйте следующее:

Пример 1:

ls | echo - Это ничего не сделает с тех пор echo не знает, как обработать вход, который он получает. Теперь в этом случае, если мы используем xargs это обработает вход способом, который может быть обработан правильно echo (например: Как одна строка информации)

ls | xargs echo - Это произведет всю информацию от ls в одной строке

Пример 2:

Скажем, у меня есть несколько goLang файлов в названной папке, идут. Я искал бы их с чем-то вроде этого:

find go -name *.go -type f | echo - Но если символ вертикальной черты там и echo в конце это не работало бы.

find go -name *.go -type f | xargs echo - Здесь это работало бы благодаря xargs но если я хотел каждый ответ от find команда в одной строке, я сделал бы следующее:

find go -name *.go -type f | xargs -0 echo - В этом случае, тот же вывод от find показали бы echo.

Команды как cp, echo, rm, less и другие, которым нужен лучший способ обработать вход, извлекают пользу при использовании с xargs.

5
ответ дан 23 November 2019 в 01:12

Другие вопросы по тегам:

Похожие вопросы: