Comando para preceder cadeia de caracteres para cada linha?

24

Procurando por algo assim? Alguma idéia?

cmd | prepend "[ERRORS] "

[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
    
por user14645 09.10.2009 / 01:17

6 respostas

34
cmd | while read line; do echo "[ERROR] $line"; done

tem a vantagem de usar somente o built-in bash para que menos processos sejam criados / destruídos, então deve ser mais rápido que o awk ou o sed

.     
por 09.10.2009 / 07:23
36

Tente isto:

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

Felicidades

    
por 09.10.2009 / 01:32
10

Com todo o crédito devido a @grawity, estou enviando o comentário dele como resposta, já que parece a melhor resposta aqui para mim.

sed 's/^/[ERROR] /' cmd
    
por 31.01.2012 / 18:38
6

Eu criei um repositório do GitHub para fazer alguns testes de velocidade.

O resultado é:

  • No caso geral, awk é o mais rápido. sed é um pouco mais lento e perl não é muito mais lento que sed . Aparentemente, todas essas linguagens são altamente otimizadas para processamento de texto.
  • Em situações muito especiais, em que os garfos dominam, executar o script como um script ksh compilado ( shcomp ) pode economizar ainda mais tempo de processamento. Por outro lado, bash é muito lento comparado aos scripts ksh compilados.
  • A criação de um binário vinculado estaticamente para vencer awk parece não valer o esforço.

Em contraste, python é muito lento, mas eu não testei um caso compilado, porque geralmente não é o que você faria em um caso de script.

As seguintes variantes são testadas:

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] $_"'

Duas variantes binárias de uma das minhas ferramentas (embora não seja otimizada para velocidade):

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

Python em buffer:

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

E Python sem buffer:

python -uSc 'import sys
while 1:
 line = sys.stdin.readline()
 if not line: break
 print "[TEST]",line,'
    
por 22.02.2014 / 05:31
4
cmd | sed 's/.*/[ERROR] &/'
    
por 09.10.2009 / 02:12
2

Eu queria uma solução que lidasse com stdout e stderr, então escrevi prepend.sh e coloquei no meu caminho:

#!/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)

Agora, posso executar apenas prepend.sh "[ERROR]" cmd ... para preceder "[ERROR]" na saída de cmd e ainda ter stderr e stdout separados.

    
por 02.09.2011 / 11:39