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?


18

findlệnh có thể xuất tên của các tệp dưới dạng chuỗi được phân tách bằng null (nếu -print0được cung cấp) và xargscó thể sử dụng chúng với -0tùy chọn được bật. Nhưng ở giữa, thật khó để thao tác mà bộ sưu tập các tập tin - sortlệnh có -zcông tắc, mà làm cho nó có thể sắp xếp các tập tin, nhưng headtailkhông có chúng.

Làm thế nào tôi có thể làm headtailtrên các đầu vào được phân tách bằng null một cách thuận tiện? (Tôi luôn có thể tạo một kịch bản ruby ​​ngắn & chậm, nhưng tôi hy vọng rằng có thể có một cách tốt hơn)

Câu trả lời:


21

GNU headtailkể từ coreutils phiên bản 8.25 có một -ztùy chọn cho điều đó.

Với các phiên bản cũ hơn hoặc cho các hệ thống không phải GNU, bạn có thể thử và trao đổi \0\n:

find ... -print0 |
  tr '\0\n' '\n\0' |
  head |
  tr '\0\n' '\n\0'

Lưu ý rằng một số headhiện thực không thể đối phó với các nhân vật NUL (và họ không phải bởi POSIX), nhưng nơi tìm sự ủng hộ -print0, headvà các tiện ích văn bản nói chung hỗ trợ các ký NUL.

Bạn cũng có thể sử dụng một hàm để bọc bất kỳ lệnh nào giữa hai trs:

nul_terminated() {
  tr '\0\n' '\n\0' | "$@" | tr '\0\n' '\n\0'
}

find ... -print0 | nul_terminated tail -n 12 | xargs -r0 ...

Hãy nhớ rằng dưới nul_terminated, một \0có nghĩa là một nhân vật dòng mới. Vì vậy, ví dụ, để thay thế \nbằng _:

find . -depth -name $'*\n*' -print0 | nul_terminated sed '
  p;h;s,.*/,,;s/\x0/_/g;H;g;s,[^/]*\n,,' | xargs -r0n2 mv

( \x0cũng là một phần mở rộng GNU).

Nếu bạn cần chạy nhiều hơn một lệnh lọc , bạn có thể làm:

find ... -print0 |
  nul_terminated cmd1 |
  nul_terminated cmd2 | xargs -r0 ...

Nhưng điều đó có nghĩa là chạy một vài trlệnh dư thừa . Ngoài ra, bạn có thể chạy:

find ... -print0 | nul_terminated eval 'cmd1 | cmd2' | xargs -r0 ...

2
Điều này không đánh bại lý do chính - để sử dụng \x0thay vì \nphân định các giá trị? (Để bạn có thể đối phó với các giá trị có thể chứa \n)
Thedward

@Thedward, không, ngược lại, -print0 | tr '\n\0' '\0\n'các dòng biểu thị đường dẫn tệp nơi các ký tự dòng mới trong chúng đã được chuyển đổi thành \0. Vì vậy, nếu bạn lấy lại dòng đầu tiên head -n 1và chuyển đổi \0lại dòng mới thành dòng mới tr '\0\n' '\n\0', bạn đã có đường dẫn tệp đầu tiên được phân định bằng NUL với các ký tự dòng mới được nhúng.
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.