Đếm các mục được phân định bằng nul trong tệp


8

Tôi có một tập lệnh shell sử dụng find -print0để lưu danh sách các tệp sẽ được xử lý thành một tệp tạm thời. Là một phần của việc ghi nhật ký tôi muốn xuất số lượng tệp được tìm thấy và vì vậy tôi cần một cách để có được số lượng đó. Nếu -print0tùy chọn không được sử dụng cho an toàn, tôi có thể sử dụng wc -lđể lấy số đếm.


Câu trả lời:


11

Một số tùy chọn:

tr -cd '\0' | wc -c

tr '\n\0' '\0\n' | wc -l      # Generic approach for processing NUL-terminated
                              # records with line-based utilities (that support
                              # NUL characters in their lines like GNU ones).

grep -cz '^'                  # GNU grep

sed -nz '$='                  # recent GNU sed, no output for empty input

awk -vRS='\0' 'END{print NR}' # not all awk implementations

Lưu ý rằng đối với đầu vào chứa dữ liệu sau ký tự NUL cuối cùng (hoặc đầu vào không trống không có ký tự NUL), các trcách tiếp cận sẽ luôn đếm số lượng ký tự NUL, nhưng các awk/ sed/ grepcách tiếp cận sẽ tính một bản ghi bổ sung cho các byte bổ sung đó .


Tôi đã đo những thứ này trên 5 GB dữ liệu ngẫu nhiên ( head -c 5G /dev/urandom > f). Kết quả: grep 1.7s (tương tự grep -Fcz '') • tr + wc-c 7.7s • tr + wc-l 7.4s • sed 34.7s • awk 1m11.7s
Socowi

@Socowi, YMMV với việc thực hiện và bản địa. Với GNU awk, bạn sẽ muốn đặt ngôn ngữ thành C(hoặc bất kỳ ký tự nào không sử dụng các ký tự đa nhân),LC_ALL=C awk ... < f
Stéphane Chazelas

Cảm ơn đã gợi ý. Tôi đã sử dụng LC_ALL=Csortnơi nó không tăng tốc mọi thứ, vì vậy May mắn thay tôi vẫn có tệp từ trước đó: LC_ALL=C awk ...mất 6,7 giây.
Socowi

4

Phương pháp tốt nhất tôi có thể nghĩ đến là sử dụng grep -zc '.*'. Điều này hoạt động, nhưng cảm thấy sai khi sử dụng grep với một mẫu sẽ phù hợp với bất cứ điều gì.


1

Với perl:

perl -0ne 'END {print $.}'

hoặc là:

perl -nle 'print scalar split "\0"'

hoặc là:

perl -nle 'print scalar unpack "(Z*)*", $_'

Người đầu tiên sẽ tính một bản ghi bổ sung nếu có dữ liệu sau NUL cuối cùng. Hai cái khác không hoạt động nếu đầu vào chứa các ký tự dòng mới.
Stéphane Chazelas

@ StéphaneChazelas: Ôi, tệ quá. Bạn có thể đưa ra bất kỳ cải thiện?
cuonglm

Tôi sẽ chỉ giữ cái đầu tiên, và đề cập đến thực tế là nó tính một bản ghi không phân định (trái với wc -l) như một ghi chú (vì nó có thể được muốn).
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.