Đặt một văn bản ở trước mỗi dòng mới mà chương trình in ra thiết bị xuất chuẩn


9

Vì vậy, tôi muốn thực hiện một số ghi nhật ký và do đó, muốn đặt một ngày trước đầu ra của tập lệnh bash. Vấn đề là có nhiều dòng đầu ra. Tôi chỉ có thể đặt ngày trước khi toàn bộ đầu ra. Nhưng sau đó tôi có một dòng không có ngày trong nhật ký. Tất nhiên tôi có thể giả sử ngày từ dòng trên là như nhau, nhưng tôi đã hy vọng có một giải pháp. Cảm ơn trước!

Đây là kịch bản của tôi gọi một kịch bản khác:

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

Đây là đầu ra:

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

Và đó là những gì tôi muốn có:

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

Tôi không cho rằng bạn chỉ có thể thay đổi kịch bản thứ hai?
jmetz

Không, thật không may. Đó là lý do tại sao tôi đến đây.
tzippy

Câu trả lời:




2

Bạn có thể dùng awk

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

awklấy một luồng đầu vào và sửa đổi đầu ra của nó. Kịch bản này đang nói "in d theo sau là đầu ra ban đầu", sau đó dnhập ngày.


1
Điều này không đánh giá datebiểu thức chỉ một lần là tốt, sao cho tất cả các dòng như vậy in cùng một lúc?
Daniel Beck

@DanielBeck Có, đúng vậy - Tôi đã cho rằng nó đang chọn ngày mỗi lần nhưng chỉ cần hoàn thành bài kiểm tra của mình đủ nhanh
Paul

1

Điều này sẽ in ngày và giờ hiện tại trước mỗi dòng đầu ra của ./script.sh:

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

Làm thế nào nó hoạt động

  • set -ftắt mở rộng bash (hoặc echo *sẽ không in dấu hoa thị thực tế).

  • while read -r LINE; do ... donelưu một dòng đầu ra trong biến $LINEvà thực thi ..., cho đến khi tất cả các dòng được xử lý.

  • echo $ (ngày "+% F% T"): "$ LINE" in dòng với thời gian và ngày hiện tại.

  • set +f bật mở rộng bash trở lại, vì vậy nó sẽ không can thiệp vào phần còn lại của tập lệnh bash của bạn.


Nó chỉ được đánh giá một lần, vì vậy mọi lần sedchèn vào cùng một ngày, từ ngay trước khi bắt đầu tập lệnh thứ hai. Có thể không phải là những gì người dùng muốn ...
Daniel Beck

Tôi không nghĩ rằng nỗ lực này cũng sẽ làm việc. AFAIK, toàn bộ khung con được đánh giá hoàn toàn trước, sau đó vòng lặp được duyệt qua. Vì vậy, bây giờ thời gian là từ sau khi thực hiện.
Daniel Beck

Ví dụ của bạn không hoạt động, vì bạn chỉ trì hoãn đầu ra, không thực hiện ls. Chỉ cần thử kịch bản của bạn với các mục sau script.sh: #!/bin/bash(dòng mới)echo 1 ; sleep 1 ; echo 2 ; sleep 2 ; echo 3 ; sleep 3 ; echo 4
Daniel Beck

Sử dụng readvới một whilevòng lặp thay vì một vòng lặp for.
chepner

@chepner: Ý kiến ​​hay.
Dennis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.