วางข้อความไว้ด้านหน้าบรรทัดใหม่ทุกบรรทัดที่โปรแกรมพิมพ์ไปยัง stdout


9

ดังนั้นฉันต้องการบันทึกบางอย่างและต้องการใส่วันที่หน้าเอาต์พุตสคริปต์ของ bash ปัญหาคือมีเอาต์พุตหลายบรรทัด ฉันสามารถใส่วันที่ก่อนหน้าผลลัพธ์ทั้งหมดเท่านั้น แต่ฉันมีบรรทัดที่ไม่มีวันที่ในบันทึก แน่นอนฉันสามารถสมมติวันที่จากบรรทัดด้านบนได้เหมือนกัน แต่ฉันหวังว่าจะมีทางออก ขอบคุณล่วงหน้า!

นี่คือสคริปต์ของฉันที่เรียกใช้สคริปต์อื่น:

#!/bin/sh
echo $(date "+%F %T") : starting script
echo $(date "+%F %T") : $(./script.sh)
echo $(date "+%F %T") :script ended

นี่คือผลลัพธ์:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
second line of output
2012-07-26 15:35:17 : script ended

และนั่นคือสิ่งที่ฉันต้องการ:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
2012-07-26 15:35:15 : second line of output
2012-07-26 15:35:17 : script ended

ฉันไม่คิดว่าคุณสามารถเปลี่ยนสคริปต์ตัวที่สองได้ใช่ไหม
jmetz

ไม่น่าเสียดาย นั่นเป็นเหตุผลที่ฉันมาที่นี่
tzippy

2
ที่เกี่ยวข้อง: stackoverflow.com/questions/21564/ …นอกจากนี้: stackoverflow.com/a/1508098/259953
Der Hochstapler

คำตอบ:


9

ตามคำถามที่คล้ายกันใน Stack Overflowมี 2 ​​ตัวเลือกที่ยอดเยี่ยม

awk ( คำตอบ )

<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'

คำอธิบายประกอบ ( คำตอบ )

คำอธิบายประกอบเป็นสคริปต์ทุบตีขนาดเล็กที่สามารถได้รับโดยตรงผ่านลิงก์ที่ให้ไว้ที่นี่หรือบนระบบที่ใช้เดเบียนผ่านแพคเกจdevscripts(ในรูปแบบของannotate-output)


3

ฉันคิดว่าคุณสามารถใช้ awk สำหรับสิ่งนี้:

./script.sh | awk '{ print strftime()" : "$0; }'

(ดูhttp://www.gnu.org/software/gawk/manual/html_node/Time-Functions.htmlสำหรับการจัดรูปแบบวันที่ส่งคืนโดย strftime ())


2
awk: calling undefined function strftime- สิ่งนี้เฉพาะเจาะจงgawkหรือไม่
Daniel Beck

ตอนนี้คุณพูดถึงมันแล้วใช่ว่าจะเป็น: /
Flinth

2

คุณสามารถใช้ได้ awk

./script.sh | awk '{ print d,$1}' "d=$(date "+%F %T")"

awkใช้อินพุตสตรีมและแก้ไขเอาต์พุต สคริปต์นี้กำลังพูดว่า "print d ตามด้วยผลลัพธ์ต้นฉบับ" จากนั้นเติมdด้วยวันที่


1
นี่ไม่ได้ประเมินการdateแสดงออกเพียงครั้งเดียวเช่นกันเพื่อให้ทุกบรรทัดดังกล่าวพิมพ์ในเวลาเดียวกันได้หรือไม่
Daniel Beck

@DanielBeck ใช่มัน - ฉันคิดว่ามันเป็นวันที่ในแต่ละครั้ง แต่เพิ่งจะทำแบบทดสอบเสร็จเร็วพอ
พอล

1

สิ่งนี้จะพิมพ์วันที่และเวลาปัจจุบันก่อนแต่ละบรรทัดของเอาต์พุต./script.sh:

set -f
./script.sh | while read -r LINE; do echo $(date "+%F %T") : "$LINE"; done
set +f

มันทำงานอย่างไร

  • set -fจะปิดการขยายตัวทุบตี (หรือecho *จะไม่พิมพ์ดอกจันจริง)

  • while read -r LINE; do ... doneบันทึกเอาต์พุตหนึ่งบรรทัดในตัวแปร$LINEและดำเนินการ...จนกว่าจะประมวลผลทุกบรรทัด

  • echo $ (วันที่ "+% F% T"): "$ LINE" พิมพ์บรรทัดที่มีเวลาและวันที่ปัจจุบัน

  • set +f เปิดใช้การขยาย bash อีกครั้งดังนั้นจึงไม่รบกวนส่วนที่เหลือของสคริปต์ bash ของคุณ


มันได้รับการประเมินเพียงครั้งเดียวดังนั้นทุก ๆsedแทรกวันที่เดียวกันจากก่อนที่จะเริ่มสคริปต์ที่สอง ดูเหมือนจะไม่ใช่สิ่งที่ผู้ใช้ต้องการ ...
Daniel Beck

ฉันไม่คิดว่าความพยายามนี้จะได้ผลเช่นกัน AFAIK, subshell ทั้งหมดได้รับการประเมินอย่างสมบูรณ์ก่อนจากนั้นจึงทำการวนซ้ำ ตอนนี้เวลามาจากหลังการประหารชีวิต
Daniel Beck

lsตัวอย่างเช่นคุณไม่ทำงานเนื่องจากคุณเพียงชะลอการส่งออกไม่ได้การดำเนินการของ เพียงลองใช้สคริปต์ของคุณดังต่อไปนี้script.sh: #!/bin/bash(ขึ้นบรรทัดใหม่)echo 1 ; sleep 1 ; echo 2 ; sleep 2 ; echo 3 ; sleep 3 ; echo 4
Daniel Beck

ใช้readกับwhileวงวนแทน for for loop
chepner

@chepner: ความคิดที่ดี
Dennis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.