각 줄 앞에 문자열을 추가하는 명령? prepend “[ERRORS] ” [ERROR]

이와 같은 것을 찾고 계십니까? 어떤 아이디어?

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은 멋진 bash 기능을 만들 수도 있다고 지적합니다. 다음과 같이 정의하십시오.

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

다음과 같이 사용할 수 있습니다.

cmd | prepend "[ERROR] "

답변

이 시도:

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

건배


답변

@grawity에 대한 모든 정당한 인정을 받아, 나는 여기에 가장 좋은 대답 인 것처럼 그의 의견을 답변으로 제출하고 있습니다.

sed 's/^/[ERROR] /' cmd

답변

속도 테스트를 수행하기 위해 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 -uSc 'import sys
for line in sys.stdin: print "[TEST]",line,'

그리고 파이썬은 버퍼링되지 않았습니다.

python -uSc 'import sys
while 1:
 line = sys.stdin.readline()
 if not line: break
 print "[TEST]",line,'

답변

cmd | sed 's/.*/[ERROR] &/'

답변

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 ...“[ERROR]”앞에 출력을 추가 cmd하고 stderr과 stdout을 별도로 가질 수 있습니다.