답변:
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] "
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
. bash 스크립트는 그것이하는 일에는 좋지만 질문하지 않은 질문에 대답하는 것 같습니다.
sed X cmd
읽고 cmd
실행하지 않습니다. 하나 cmd | sed 's/^/[ERROR] /'
또는 sed 's/^/[ERROR] /' <(cmd)
나 cmd > >(sed 's/^/[ERROR] /')
. 그러나 후자를 조심하십시오. 그럼에도 불구하고 백그라운드 cmd
에서 sed
실행 의 리턴 값에 액세스 할 수 있으므로 cmd가 완료된 후 출력이 표시 될 수 있습니다 . 그래도 파일에 로그인하는 데 좋습니다. 그리고 awk
아마도보다 빠릅니다 sed
.
alias lpad="sed 's/^/ /'"
. 오류 대신 4 개의 선행 공백을 삽입하십시오. 이제 마법의 해트트릭 : ls | lpad | pbcopy
같은 4 자리 표시를 함께 LS 출력을 앞에 추가됩니다 마크 다운 에 대한 코드 는 (클립 보드를 붙여 의미 pbcopy이 직접 StackOverflow의 또는 기타 가격 인하 컨텍스트에 맥에, 그것을 움켜). 할 수 없습니다 된 awk 이 하나의 승리 때문에 (첫 번째 시도에) 대답. 동안 읽기 솔루션은 앨리어스 수 있지만 나는이 찾을 나오지도 더 표현. 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 -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,'
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 ...
"[ERROR]"앞에 출력을 추가 cmd
하고 stderr과 stdout을 별도로 가질 수 있습니다.
>(
내가 해결할 수 없었던 서브 쉘 과 관련하여 무언가가있었습니다 . 스크립트가 완료되는 것처럼 보였고 프롬프트가 반환 된 후 출력이 터미널에 도착 하여 약간 지저분했습니다. 나는 결국 여기에 대답을 생각해 냈습니다. stackoverflow.com/a/25948606/409638