Chuyển đổi dòng mới thành null-deliated khi sử dụng đuôi


20

Làm cách nào tôi có thể thay đổi đầu ra từ tailđể sử dụng các dòng kết thúc null thay vì dòng mới?

Câu hỏi của tôi tương tự như câu hỏi này: Làm thế nào để thực hiện `head` và` tail` trên đầu vào được phân tách bằng null trong bash? , nhưng khác ở chỗ tôi muốn làm một cái gì đó như:

tail -f myFile.txt | xargs -i0 myCmd {} "arg1" "arg2"

Tôi không sử dụng find, và vì vậy không thể sử dụng-print0

Tất cả điều này là để tránh lỗi xảy ra trong xargs:

xargs: unmatched double quote;
    by default quotes are special to xargs unless you use the -0 option

Câu trả lời:


26

Nếu bạn muốn 10 dòng cuối cùng:

tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

Nhưng với GNU xargs, bạn cũng có thể đặt dấu phân cách thành dòng mới với:

tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2

( -0viết tắt của -d '\0').

Có thể, bạn cũng có thể thoát khỏi mọi nhân vật:

tail myFile.txt | sed 's/./\\&/g' | xargs -I{} myCmd {} arg1 arg2

Hoặc trích dẫn từng dòng:

tail myFile.txt | sed 's/"/"\\""/g;s/.*/"&"/' | xargs -I{} myCmd {} arg1 arg2

Nếu bạn muốn 10 bản ghi được phân tách bằng NUL cuối cùng của myFile.txt(nhưng sau đó sẽ không phải là tệp văn bản), bạn phải chuyển đổi \nthành \0trước khi gọi tail, điều đó có nghĩa là tệp sẽ phải được đọc đầy đủ:

tr '\n\0' '\0\n' < myFile.txt |
  tail |
  tr '\n\0' '\0\n' |
  xargs -r0i myCmd {} arg1 arg2

Chỉnh sửa (vì bạn đã thay đổi tailthành tail -ftrong câu hỏi của bạn):

Cái cuối cùng ở trên rõ ràng không có ý nghĩa cho tail -f.

Một xargs -d '\n'cái sẽ hoạt động, nhưng đối với những cái khác, bạn sẽ gặp vấn đề về bộ đệm. Trong:

tail -f myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

trđệm đầu ra của nó khi nó không đi đến một thiết bị đầu cuối (ở đây, một đường ống). IE, nó sẽ không ghi bất cứ điều gì cho đến khi nó tích lũy được một bộ đệm đầy (giống như 8kiB) dữ liệu để ghi. Có nghĩa là myCmdsẽ được gọi theo đợt.

Trên một hệ thống GNU hoặc FreeBSD, bạn có thể thay đổi hành vi của đệm trvới stdbuflệnh:

tail -f myFile.txt | stdbuf -o0 tr '\n' '\0' |
  xargs -r0i myCmd {} arg1 arg2

Tôi thực sự có ý định sử dụng tùy chọn -f ở đuôi, nó liên tục in các dòng khi chúng đến. Tôi không nghĩ điều này sẽ quan trọng, nhưng rõ ràng là nó có. Với tùy chọn -f, giải pháp của bạn không hoạt động.
Lars

tail -f myFile.txt | xargs -r0i -d '\n' myCmd "{}" "||" "||"vẻ như để làm việc! Cảm ơn.
Lars

@Lars, xin lỗi, -itùy chọn có một đối số tùy chọn, vì vậy -i0sẽ không hoạt động. Tất cả chúng nên hoạt động tail -fngoại trừ cái cuối cùng, nhưng hãy cẩn thận vì bộ đệm, sẽ có độ trễ trước khi xargsnhận đầu vào từ đó tr. Bạn có thể thay đổi điều đó bằng cách chạy stdbuf -o0 tr '\n' '\0'thay vì tr '\n' '\0'.
Stéphane Chazelas
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.