Выполнить команду однажды на строку переданного по каналу входа?

Установите полужирную/цветную подсказку. Из cyberciti.biz и BashFAQ

# 'tput bold' will work regardless of the foreground and background colors.
# Place the tput output into variables, so they are only execd once.
bold=$(tput bold) # This could also be a color.
reset=$(tput sgr0)
export PS1="\u@\[$bold\]\h\[$reset\]:\w \$ "

Мне также удалось найти настройки цветов, которые широко поддерживаются, и которые не печатают символы напыщенности речи в более старых средах (даже FreeBSD4!), и, кажется, хорошо работает, если TERM=vt100, xterm, xterm-окрашивают. (По большей части). От моего .bashrc:

# Set some options, based on the OS
OS=`uname -s` 

case "$OS" in
    "SunOS" ) 
        # Solaris ls doesn't allow color, so use special characters
        LS_OPTS='-F'
        alias  ls='ls ${LS_OPTS}'
        ;;
    "Linux" )
        # GNU ls supports colors!
        # See dircolors to customize colors
        export LS_OPTS='--color=auto' 
        alias  ls='ls ${LS_OPTS}'

        # Get color support for 'less'
        export LESS="--RAW-CONTROL-CHARS"

        # Use colors for less, man, etc.
        [[ -f ~/.LESS_TERMCAP ]] && . ~/.LESS_TERMCAP

        export GREP_OPTIONS="--color=auto"

        ;;
    "Darwin"|"FreeBSD")

        # Most FreeBSD & Apple Darwin supports colors
        export CLICOLOR=true
        # Get color support for 'less'
        export LESS="--RAW-CONTROL-CHARS"

        # Use colors for less, man, etc.
        [[ -f ~/.LESS_TERMCAP ]] && . ~/.LESS_TERMCAP

        export GREP_OPTIONS="--color=auto"
        ;;
    * ) 
        echo "Unknown OS [$OS]"
        ;;
esac

170
17.02.2011, 06:26
11 ответов

Это что xargs делает.

... | xargs command
95
27.01.2020, 19:28
  • 1
    Не совсем. printf "foo bar\nbaz bat" | xargs echo whee уступит whee foo bar baz bat. Возможно, добавьте -L или -n опции? –  Jander 17.02.2011, 07:17
  • 2
    @Jander вопрос был довольно общим, таким образом, я дал общий инструмент. Правда, необходимо будет скорректировать его поведение с опциями в зависимости от определенных обстоятельств. –  Keith 17.02.2011, 07:25
  • 3
    ... | TR '\n' '\0' | xargs-0 –  vrdhn 17.02.2011, 13:12
  • 4
    как, "определенные обстоятельства, которые дают правильный ответ на вопрос". :) –  mattdm 17.02.2011, 20:17
  • 5
    Если Вы хотите видеть надлежащий способ сделать это с xargs, см. мой ответ ниже. –  Michael Goldshteyn 30.06.2015, 19:08

В Bash или любой другой оболочке стиля Границы (пепел, ksh, zsh, …):

while read -r line; do command "$line"; done

read -r читает одну строку из стандартного входа (read без -r интерпретирует обратные косые черты, Вы не хотите это). Таким образом можно сделать любое из следующего:

$ command | while read -r line; do command "$line"; done  

$ while read -r line; do command "$line"; done <file
114
27.01.2020, 19:28
  • 1
    , Когда я попробовал tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; done это не работало. Это работало с файлом, переданным по каналу в while цикл, работавший только с tail -f, работавший только с grep, но не с обоими каналами. Предоставление grep --line-buffered опция заставила его работать –   10.03.2012, 22:39

Я соглашаюсь с Keith, xargs является самым общим инструментом для задания.

Я обычно использую 3 подхода шага.

  • сделайте основной материал, пока у Вас нет чего-то, с чем требуется работать
  • подготовьте строку с awk, таким образом, это получает правильный синтаксис
  • затем позвольте xargs выполнить его, возможно, с помощью удара.

Существуют меньшие и более быстрые пути, но это пути почти всегда работает.

Простой пример:

ls | 
grep xls | 
awk '{print "MyJavaProg --arg1 42 --arg2 "$1"\0"}' | 
xargs -0 bash -c

2 первых строки выбирают некоторые файлы для работы с, затем awk готовит хорошую строку с командой для выполнения и некоторые аргументы, и 1$ является первым входом столбца от канала. И наконец я удостоверяюсь, что xargs отправляет эту строку для избиения, это просто выполняет его.

Это - немного излишества, но этот рецепт помог мне в большом количестве мест, так как это очень гибко.

22
27.01.2020, 19:28
  • 1
    Отметьте, xargs -0 использует пустой байт в качестве разделителя записей, таким образом, Ваш awk оператор печати должен быть printf("MyJavaProg --args \"%s\"\0",$1) –  glenn jackman 17.02.2011, 16:30
  • 2
    @glenn: Пропущенный пустой символ, обновит ответ –  Johan 18.02.2011, 14:43
  • 3
    @Johan не грандиозное предприятие, но если Вы используете awk у Вас может быть он, делают соответствие шаблона и пропускают grep например, ls | awk '/xls/ {print... –  Eric Renouf 31.05.2016, 18:19

Параллель GNU сделана для таких задач. Самое простое использование:

cat stuff | grep pattern | parallel java MyProg

Посмотрите вводное видео для узнавания больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ

15
27.01.2020, 19:28
  • 1
    Никакая реальная потребность в cat здесь с тех пор grep может непосредственно читать операции –  Eric Renouf 31.05.2016, 18:20
  • 2
  • 3
    Спасибо за ссылку я не обязательно соглашаюсь, что легче читать, но хороший знать, что это считали невнимательным. Я только теперь немного придрался бы, который ссылка на самом деле не применяет здесь, так как альтернатива не действительно < stuff grep pattern но grep pattern stuff без перенаправления или кошки, требуемой вообще. Однако, это существенно не изменяет Ваш аргумент и если Вы думаете, что это более ясно всегда использовать вещи в канале, который запускается с cat, затем питание Вам –  Eric Renouf 01.06.2016, 03:32

При контакте с потенциально несанированными исходными данными мне нравится видеть все задание, 'разъясненное' линию за линией для визуального контроля, прежде чем я выполню его (особенно, когда это - что-то разрушительное как очистка почтового ящика людей).

Таким образом, то, что я делаю, генерируют список параметров (т.е. имена пользователей), подают его в файл one-record-per-line способом, как это:

johndoe  
jamessmith  
janebrown  

Затем я открываю список в vim, и исказите его с поиском и замените выражения, пока я не получаю список полных команд, которые должны быть выполнены, как это:

/bin/rm -fr /home/johndoe  
/bin/rm -fr /home/jamessmith 

Таким образом, если Ваш regex является неполным, Вы будете видеть в том, что команда будет иметь потенциальными проблемами (т.е. /bin/rm -fr johnnyo connor). Таким образом, можно отменить regex и попробовать его снова более надежной версией его. Искажение имени известно за это, потому что трудно заботиться обо всех пограничных случаях как Van Gogh, O'Connors, Св. Clair, Smith-Wesson.

Наличие set hlsearch полезно для выполнения в этом vim, поскольку это выделит все соответствия, таким образом, можно будет легко определить, если это не соответствует или соответствует непреднамеренным способом.

После того как Ваш regex прекрасен, и он ловит все случаи, на которые можно протестировать, затем я обычно преобразовываю его в sed выражение, таким образом, он может быть полностью автоматизирован для другого выполнения.

Для случаев, где количество строк входа препятствует тому, чтобы Вы делали визуальный контроль, я настоятельно рекомендую повторение команды на экран (или еще лучше, журнал), прежде чем это выполнится, поэтому если это ошибки, Вы знаете точно, какая команда заставила это перестать работать. Затем можно вернуться к исходному regex и корректироваться еще раз.

1
27.01.2020, 19:28

Кроме того, while read цикл в оболочке рыбы (я принимаю Вас, хочет оболочку рыбы, полагая использование тега ).

command | while read line
    command $line
end

Немного моментов, которых необходимо отметить.

  • read не берет -r аргумент, и это не интерпретирует Ваши обратные косые черты для создания случая наиболее популярного способа использования легким.
  • Вы не должны заключать в кавычки $line, как в отличие от удара, рыба не делает отдельных переменных пробелами.
  • command отдельно синтаксическая ошибка (для ловли такого использования аргументов заполнителя). Замените его реальной командой.
8
27.01.2020, 19:28

Принятый ответ имеет верное представление, но ключ должен передать xargs переключатель-n1, что означает, "Выполняют команду однажды на строку вывода":

cat file... | xargs -n1 command

Или, для единственного входного файла можно избежать канала от кошка полностью и просто пойти с:

<file xargs -n1 command
180
27.01.2020, 19:28

Если программа игнорирует канал, но принимает файлы в качестве аргументов, то вы можете просто указать ей специальный файл /dev/stdin.

Я не знаком с java, но вот пример того, как вы могли бы сделать это для bash:

$ echo $'pwd \n cd / \n pwd' |bash /dev/stdin
/home/rolf
/

Символ $ необходим bash для перевода \n в символы новой строки. Я не уверен, почему.

0
20.08.2021, 13:37

Если вам нужно контролировать, где именно вводимый аргумент вставляется в вашу командную строку, или если вам нужно повторить его несколько раз, вы можете использовать xargs -I{}.

ПРИМЕР #1

Создать пустую структуру папок в another_folder, которая отражает подпапки в текущем каталоге:

    ls -1d./*/ | xargs -I{} mkdir another_folder/{}
ПРИМЕР #2

Применить операцию к списку файлов, полученному из стандартного ввода, в этом случае сделать копию каждого .htmlфайла, добавив расширение .bak:

    find. -iname "*.html" | xargs -I{} cp {} {}.bak

Из справочной страницыxargsдля MacOS/BSD:

 -I replstr
         Execute utility for each input line, replacing one or more occurrences of
         replstr in up to replacements (or 5 if no -R flag is specified) arguments
         to utility with the entire line of input.  The resulting arguments, after
         replacement is done, will not be allowed to grow beyond 255 bytes; this is
         implemented by concatenating as much of the argument containing replstr as
         possible, to the constructed arguments to utility, up to 255 bytes.  The
         255 byte limit does not apply to arguments to utility which do not contain
         replstr, and furthermore, no replacement will be done on utility itself.
         Implies -x.

Linuxxargsсправочная страница:

   -I replace-str
          Replace  occurrences of replace-str in the initial-
          arguments with names read from standard input.  Al‐
          so,  unquoted  blanks do not terminate input items;
          instead the separator  is  the  newline  character.
          Implies -x and -L 1.
14
20.08.2021, 13:37

Я предпочитаю это -, позволяющее использовать многострочные -команды и понятный код

find -type f -name filenam-pattern* | while read -r F
do
  echo $F
  cat $F | grep 'some text'
done

ссылкаhttps://stackoverflow.com/a/3891678/248616

0
20.08.2021, 13:37

Здесь можно использовать копипасту:

cat list.txt | xargs -I{} command parameter {} parameter

Элемент из списка будет помещен на место {}, а остальная часть команды и параметры будут использоваться как -.

4
20.08.2021, 13:37

Теги

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