กำลังมองหาอะไรแบบนี้? ความคิดใด ๆ
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 builtins เพื่อให้กระบวนการสร้าง / ทำลายน้อยลงดังนั้นจึงควรมีการสัมผัสที่เร็วกว่า 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
รันในพื้นหลังดังนั้นจึงเป็นไปได้ว่าคุณจะเห็นผลลัพธ์หลังจาก cmd เสร็จสิ้น ดีสำหรับการเข้าสู่ไฟล์แม้ว่า และโปรดทราบว่าอาจจะเร็วกว่าawk
sed
alias lpad="sed 's/^/ /'"
. แทนข้อผิดพลาดฉันใส่ 4 ช่องว่างนำหน้า ตอนนี้สำหรับเคล็ดลับมายากลที่ ls | lpad | pbcopy
จะส่งออกย่อหน้า LS 4 พื้นที่ซึ่งเป็นเครื่องหมายMarkdownสำหรับรหัสซึ่งหมายความว่าคุณวางคลิปบอร์ด ( pbcopyคว้ามันบนแม็ค) โดยตรงใน StackOverflow หรือบริบท markdown อื่น ๆ ไม่สามารถ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,'
และงูหลาม unbuffered:
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 แยกกัน
>(
subshell เหล่านั้นที่ฉันไม่สามารถแก้ไขได้ ดูเหมือนว่าสคริปต์จะเสร็จสิ้นแล้วและผลลัพธ์ก็มาถึง terminal หลังจากที่แจ้งกลับมาซึ่งค่อนข้างยุ่ง ในที่สุดฉันก็พบคำตอบได้ที่นี่stackoverflow.com/a/25948606/409638