Я хочу выполнить команду Java один раз для каждого матча ls | grep pattern -
. В этом случае, я думаю, я мог бы сделать, find pattern -exec java MyProg '{}' \;
но мне любопытно, в общем случае - есть ли простой способ сказать «выполнить команду один раз для каждой строки стандартного ввода»? (В рыбе или баш.)
162
printf "foo bar\nbaz bat" | xargs echo whee
дастwhee foo bar baz bat
. Может быть, добавить-L
или-n
варианты?Принятый ответ имеет право идеи, но ключ , чтобы пройти
xargs
на-n1
переключатель, что означает «Выполнить команду один раз в строку вывода:»Или, для одного входного файла вы можете полностью исключить канал
cat
и просто использовать:источник
xargs
к не работать , еслиstdin
пусто:--no-run-if-empty
-r
Если стандартный ввод не содержит никаких nonblanks, не выполнить команду. Обычно команда запускается один раз, даже если нет ввода. Эта опция является расширением GNU.command
?В Bash или любой другой оболочке в стиле Bourne (ash, ksh, zsh,…):
read -r
читает одну строку из стандартного ввода (read
без-r
интерпретации обратной косой черты, вы этого не хотите). Таким образом, вы можете сделать одно из следующего:источник
tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; done
это не сработало. Он работал с файлом, переданным вwhile
цикл, работал только с темtail -f
, работал только сgrep
, но не с обоими каналами. Предоставлениеgrep
в--line-buffered
варианте сделал его работуcommand | while read -r line; do echo "$line" | command ; done
Я согласен с Китом, xargs - самый общий инструмент для работы.
Я обычно использую трехэтапный подход.
Есть меньшие и более быстрые способы, но эти способы почти всегда работают.
Простой пример:
2 первые строки выбирают несколько файлов для работы, затем awk готовит красивую строку с командой для выполнения и некоторыми аргументами, а $ 1 - это первый вход столбца из канала. И, наконец, я убедился, что xargs отправляет эту строку в bash, которая просто выполняет ее.
Это немного излишне, но этот рецепт помог мне во многих местах, так как он очень гибкий.
источник
xargs -0
что в качестве разделителя записей используется нулевой байт, поэтому ваш оператор печати на awk должен выглядеть следующим образомprintf("MyJavaProg --args \"%s\"\0",$1)
awk
вы можете сделать так, чтобы он соответствовал шаблону и пропустил,grep
например,ls | awk '/xls/ {print...
GNU Parallel создан для такого рода задач. Самое простое использование:
Посмотрите вступительное видео, чтобы узнать больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ
источник
cat
здесь нет, так как выgrep
можете непосредственно прочитать файл< stuff grep pattern
ноgrep pattern stuff
без перенаправления или cat не требуется вообще. Тем не менее, это существенно не меняет ваш аргумент, и если вы думаете, что будет яснее всегда использовать вещи в трубе, которая начинается сcat
, тогда власть для васКроме того,
while read
сделайте петлю в рыбных раковинах (я предполагаю, что вы хотите рыбные раковины, учитывая, что вы использовали рыбную бирку).Несколько замечаний.
read
не принимает-r
аргументов и не интерпретирует обратную косую черту, чтобы облегчить наиболее распространенный вариант использования.$line
, поскольку в отличие от bash, fish не разделяет переменные по пробелам.command
сама по себе является синтаксической ошибкой (чтобы отловить такое использование аргументов-заполнителей). Замените его настоящей командой.источник
while
нужно в паре сdo
&done
вместоend
?Если вам нужно контролировать, где именно вводимый аргумент вставляется в вашу командную строку, или если вам нужно повторить его несколько раз, вам нужно использовать
ПРИМЕР № 1xargs -I{}
.Создайте пустую структуру папок,
ПРИМЕР № 2another_folder
которая будет отражать подпапки в текущем каталоге:Примените операцию к списку файлов из stdin, в этом случае сделайте копию каждого
.html
файла, добавив.bak
расширение:Со
xargs
страницы руководства для MacOS / BSD :xargs
Страница руководства по Linux :источник
Имея дело с потенциально неанизированными входами, я хотел бы видеть всю работу, "прописанную", построчно для визуального осмотра, прежде чем запускать ее (особенно когда это что-то разрушительное, например, очистка почтовых ящиков людей).
Поэтому я создаю список параметров (т. Е. Имена пользователей), передаю его в файл по одной записи на строку, например:
Затем я открываю список
vim
и изменяю его с помощью выражений поиска и замены, пока не получу список полных команд, которые должны быть выполнены, например:Таким образом, если ваше регулярное выражение неполное, вы увидите, в какой команде будут возникать потенциальные проблемы (т.е.
/bin/rm -fr johnnyo connor
). Таким образом, вы можете отменить свое регулярное выражение и попробовать его снова с более надежной версией. Известно, что искажение имен известно, потому что трудно позаботиться обо всех крайних случаях, таких как Ван Гог, О'Коннорс, Сент-Клер, Смит-Вессон.Наличие
set hlsearch
полезно для этогоvim
, так как оно подсвечивает все совпадения, так что вы можете легко определить, не совпадает ли оно или совпадает непреднамеренным образом.После того, как ваше регулярное выражение станет идеальным, и оно поймает все случаи, для которых вы можете проверить / подумать, я обычно преобразую его в выражение sed, чтобы его можно было полностью автоматизировать для следующего запуска.
В тех случаях, когда количество строк ввода не позволяет выполнить визуальный осмотр, я настоятельно рекомендую выводить команду на экран (или, что еще лучше, в журнал) перед ее выполнением, поэтому, если она выдает ошибку, вы точно знаете, какая команда вызвала это потерпеть неудачу. Затем вы можете вернуться к исходному регулярному выражению и настроить еще раз.
источник
Если программа игнорирует канал, но принимает файлы в качестве аргументов, тогда вы можете просто указать его на специальный файл
/dev/stdin
.Я не знаком с Java, но вот пример того, как вы могли бы сделать это для Bash:
$ Необходим для перевода bash
\n
в новые строки. Я не уверен почему.источник
Я предпочитаю это - разрешить многострочные команды и очистить код
ссылка https://stackoverflow.com/a/3891678/248616
источник
Здесь копировальную пасту вы можете сразу использовать:
Элемент из списка будет помещен туда, где {}, а остальная часть команды и параметров будет использоваться как есть.
источник