Nếu bạn có GNU grep (luôn có trên Linux và Cygwin, đôi khi ở nơi khác), bạn có thể đếm các dòng đầu ra từgrep -o
: grep -o needle | wc -l
.
Với Perl, đây là một vài cách tôi thấy thanh lịch hơn của bạn (ngay cả khi đã được sửa ).
perl -lne 'END {print $c} map ++$c, /needle/g'
perl -lne 'END {print $c} $c += s/needle//g'
perl -lne 'END {print $c} ++$c while /needle/g'
Chỉ với các công cụ POSIX, một cách tiếp cận, nếu có thể, là chia đầu vào thành các dòng với một khớp duy nhất trước khi chuyển nó sang grep. Ví dụ: nếu bạn đang tìm kiếm toàn bộ từ, thì trước tiên hãy biến mọi ký tự không phải từ thành một dòng mới.
# equivalent to grep -ow 'needle' | wc -l
tr -c '[:alnum:]' '[\n*]' | grep -c '^needle$'
Mặt khác, không có lệnh tiêu chuẩn để thực hiện xử lý văn bản cụ thể này, vì vậy bạn cần chuyển sang sed (nếu bạn là một masochist) hoặc awk.
awk '{while (match($0, /set/)) {++c; $0=substr($0, RSTART+RLENGTH)}}
END {print c}'
sed -n -e 's/set/\n&\n/g' -e 's/^/\n/' -e 's/$/\n/' \
-e 's/\n[^\n]*\n/\n/g' -e 's/^\n//' -e 's/\n$//' \
-e '/./p' | wc -l
Đây là một giải pháp đơn giản hơn bằng cách sử dụng sed
và grep
, hoạt động cho các chuỗi hoặc thậm chí các biểu thức chính quy trong sách nhưng không thành công trong một vài trường hợp góc với các mẫu được neo (ví dụ: nó tìm thấy hai lần xuất hiện ^needle
hoặc \bneedle
trong needleneedle
).
sed 's/needle/\n&\n/g' | grep -cx 'needle'
Lưu ý rằng trong các thay thế sed ở trên, tôi thường \n
có nghĩa là một dòng mới. Đây là tiêu chuẩn trong phần mẫu, nhưng trong văn bản thay thế, về tính di động, thay thế dấu gạch chéo ngược-newline cho \n
.
grep
là được chỉ định, nhưng đối với bất cứ ai sử dụngack
, câu trả lời chỉ đơn giản làack -ch <pattern>
.