Команда для предварительного ожидания строки к каждой строке?

Не забывайте iostat, часть sysstat пакета. Если Вы хотите что-то, что легко портативный, почему бы не записать оболочке или сценарию Perl, который можно разрабатывать со временем? Это было бы хорошим способом изучить различия между системами и поправиться в сценариях. Можно обычно анализировать большую часть информации из proc или просто оборачивать все те инструменты.

36
задан 9 October 2009 в 02:17
7 ответов
cmd | while read line; do echo "[ERROR] $line"; done

имеет преимущество только использования удара builtins, таким образом, меньше процессов будет создано/уничтожено так, это должно быть касание быстрее, чем awk или sed.

@tzrik указывает, что мог бы также сделать хорошую функцию удара. Определение его как:

function prepend() { while read line; do echo "${1}${line}"; done; }

позволил бы этому использоваться как:

cmd | prepend "[ERROR] "
39
ответ дан 28 November 2019 в 19:49
  • 1
    Это на самом деле только уменьшает количество процесса одним. (Но это могло бы быть быстрее, потому что никакие regexps (sed) или даже не представляют разделение в виде строки (awk), используются.) –  grawity 9 October 2009 в 10:52
  • 2
    BTW, я был любопытен на предмет производительности и здесь являюсь результатами своего простого сравнительного теста с помощью удара, sed и awk. Продвижение приблизительно 1 000 строк текста (dmesg вывод) в файл FIFO и затем чтение их как это: pastebin.ca/1606844 Похож на awk, победитель. Какие-либо идеи, почему? –  Ilya Zakreuski 9 October 2009 в 14:12
  • 3
    будьте осторожными тестами синхронизации выполнения как этот - пытаются выполнить их во всех 6 различных заказах и затем составить в среднем результаты. Различные заказы смягчить последствия кэша блока и среднее число для смягчения фоновых последствий прерывания/планирования. –  pjz 9 October 2009 в 21:25

Попробуйте это:

cmd | awk '{print "[ERROR] " $0}'

Удачи

46
ответ дан 28 November 2019 в 19:49
cmd | sed 's/.*/[ERROR] &/'
5
ответ дан 28 November 2019 в 19:49

I wanted a solution that handled stdout and stderr, so I wrote prepend.sh and put it in my path:

#!/bin/bash

prepend_lines(){
  local prepended=$1
  while read line; do
    echo "$prepended" "$line"
  done
}

tag=$1

shift

"$@" > >(prepend_lines "$tag") 2> >(prepend_lines "$tag" 1>&2)

Now I can just run prepend.sh "[ERROR]" cmd ..., to prepend "[ERROR]" to the output of cmd, and still have stderr and stdout separate.

3
ответ дан 28 November 2019 в 19:49

При всем уважении к @grawity, я отправляю его комментарий в качестве ответа, поскольку мне кажется, что это лучший ответ.

sed 's/^/[ERROR] /' cmd
13
ответ дан 28 November 2019 в 19:49

Я создал репозиторий GitHub для выполнения некоторых тестов скорости.

Результат:

  • В общем случае, awk быстрее всех. sed немного медленнее и perl не намного медленнее, чем sed. Очевидно, что все это сильно оптимизированные языки для обработки текста.
  • В очень специфических ситуациях, когда вилки доминируют, запуск вашего скрипта в виде скомпилированного ksh скрипта (shcomp) может сэкономить еще больше времени на обработку. Напротив, bash является мертвым медленным по сравнению с компилированным ksh скриптов.
  • Создание статически связанных двоичных бить awk, кажется, не стоит усилий.

В отличие от python является мертвым медленным, но я не тестировал скомпилированный случай, потому что это, как правило, не то, что вы бы сделали в таком случае сценариев.

Тестируются следующие варианты:

while read line; do echo "[TEST] $line"; done
while read -r line; do echo "[TEST] $line"; done
while read -r line; do echo "[TEST]" $line; done
while read -r line; do echo "[TEST]" "$line"; done
sed 's/^/[TEST] /'
awk '{ print "[TEST] " $0 }'
awk -vT="[TEST] " '{ print T $0 }'
awk -vT="[TEST]" '{ print T " " $0 }'
awk -vT="[TEST]" 'BEGIN { T=T " "; } { print T $0 }'
T="[TEST] " awk '{ print ENVIRON["T"] $0 }'
T="[TEST]" awk '{ print ENVIRON["T"] " " $0 }'
T="[TEST]" awk 'BEGIN { T=ENVIRON["T"] " " } { print T $0 }'
perl -ne 'print "[TEST] $_"'

Два бинарных варианта одного из моих инструментов (он не оптимизирован под скорость, однако):

./unbuffered.dynamic -cp'[TEST] ' -q ''
./unbuffered.static -cp'[TEST] ' -q ''

Python буферизован:

python -uSc 'import sys
for line in sys.stdin: print "[TEST]",line,'

А Python не буферизован:

python -uSc 'import sys
while 1:
 line = sys.stdin.readline()
 if not line: break
 print "[TEST]",line,'
8
ответ дан 28 November 2019 в 19:49
cmd | xargs -L 1 -i echo "prefix{}"

или даже проще в случае, если префикс отделен пробелами от самой строки

cmd | xargs -L 1 echo prefix

Это не очень эффективно с точки зрения производительности, но коротко для записи.

Он работает, выполняя echo один раз для каждой строки ввода. xargs позволяет также обрабатывать \ 0 -разделенные строки.

2
ответ дан 26 February 2020 в 08:02

Теги

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