Шукаєте щось подібне? Якісь ідеї?
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