Шукаєте щось подібне? Якісь ідеї?
cmd | prepend "[ERRORS] "
[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
Шукаєте щось подібне? Якісь ідеї?
cmd | prepend "[ERRORS] "
[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
Відповіді:
cmd | while read line; do echo "[ERROR] $line"; done
має перевагу лише у використанні bash вбудованих, тому буде створено / знищено менше процесів, тому це має бути дотиком швидше, ніж awk або sed.
@tzrik зазначає, що це також може зробити гарну функцію баш. Визначивши це як:
function prepend() { while read line; do echo "${1}${line}"; done; }
дозволив би використовуватись так:
cmd | prepend "[ERROR] "
sed) або навіть розбиття рядків ( awk).)
function prepend() { while read line; do echo "${1}${line}"; done; }
Спробуйте це:
cmd | awk '{print "[ERROR] " $0}'
Ура
awk -vT="[ERROR] " '{ print T $0 }'абоawk -vT="[ERROR]" '{ print T " " $0 }'
T="[ERROR] " awk '{ print ENVIRON["T"] $0 }'абоT="[ERROR]" awk '{ print ENVIRON["T"] " " $0 }'
cmd | awk '{print "['$V]' " $0}'- це слід оцінювати один раз на старті, так що без накладних витрат.
З усією належною заслугою до @grawity, я надсилаю його коментар як відповідь, оскільки це здається мені найкращою відповіддю.
sed 's/^/[ERROR] /' cmd
awkОдин-лайнер досить хороший, але я думаю , що все більше людей знайомі з sedчим awk. Баш сценарій хороший для того, що він робить, але, здається, він відповідає на питання, яке не було задано.
sed X cmdчитає cmdі не виконує його. Або cmd | sed 's/^/[ERROR] /'чи sed 's/^/[ERROR] /' <(cmd)або cmd > >(sed 's/^/[ERROR] /'). Але остерігайтеся останнього. Навіть те , що це дозволяє отримати доступ до що повертається значенням cmdв sedпрогонах в фоновому режимі, так що, швидше за все , ви побачите результат після ЦМДА готового. Хоча добре для входу у файл. І зауважте, що, awkймовірно, швидше, ніж sed.
alias lpad="sed 's/^/ /'". замість ПОМИЛКИ я вставляю 4 провідні пробіли. Тепер для магічного трюку: ls | lpad | pbcopyбуде додано ls-висновок з 4 пробілами, який позначає його як Markdown для коду , це означає, що ви вставляєте буфер обміну ( pbcopy захоплює його на macs) безпосередньо в StackOverflow або будь-який інший контекст розмітки. Чи не вдалося AWK відповідь (на 1 - й спроби) так що це один виграє. У той час як рішення для читання також може бути псевдонімом, але я вважаю цей sed більш виразним. alias
Я створив сховище 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,'
awk -v T="[TEST %Y%m%d-%H%M%S] " '{ print strftime(T) $0 }'для виведення часової позначки
Я хотів рішення, яке обробляло stdout і stderr, тому я написав prepend.shі поставив це на своєму шляху:
#!/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)
Тепер я можу просто запустити prepend.sh "[ERROR]" cmd ..., щоб додати "[ПОМИЛКУВАННЯ]" до виводу cmd, і ще мати окремі stderr та stdout.
>(що не вдалося вирішити, відбувалося з тими підрозділами. Здавалося, що сценарій завершується, і висновок надходить до терміналу після повернення підказки, який був трохи безладним. Я врешті-решт придумав відповідь тут stackoverflow.com/a/25948606/409638