Số lượng tệp không chứa chuỗi đã cho


7

Tôi đọc câu hỏi về cách tìm ra số lượng tệp có chứa một chuỗi nhất định. Điều này là có thể với grep -l "string" * | wc -l.

Có thể đảo ngược điều này, tìm số lượng tệp không chứa chuỗi đích? Tôi đã thử thêm -vtùy chọn, nhưng điều này dường như không cho kết quả đúng.

Câu trả lời:


10

Với GNU hoặc OpenBSD grep:

grep -L "string" ./* | grep -c /

9

Một cách khác của POSIX:

c=0
for f in *; do
  [ -d "$f" ] && continue
  { grep -q string || c=$(($c + 1)); } < "$f"
done
echo "$c"

Bằng cách chuyển hướng nhóm lệnh thay vì grepmột mình, chúng tôi tránh tính là 1 tệp mà chúng tôi không thể mở (như các tệp mà chúng tôi không có quyền đọc hoặc *nếu không có tệp không bị ẩn trong thư mục hiện tại).

Với GNU grep, tương đương sẽ là:

grep -d skip -L foo ./* | grep -c /

Lưu ý rằng bạn không thể sử dụng wc -lvì tên tệp có thể được tạo thành từ nhiều dòng. Có ./cũng tránh vấn đề với tên tập tin bắt đầu bằng -hoặc - (mà --không làm việc xung quanh). Lưu ý rằng nó bỏ qua các tập tin dấu chấm.


4

Đây là một cách tuân thủ POSIX, trong trường hợp bạn không có grep -L:

for file in *; do
    awk '/string/ { found=1; exit } END{ if(!found) { printf "x" } }' < "$file"
done | wc -c

1

Một cách khác của POSIX chỉ sử dụng grepwc:

COUNT_FILES=0
for i in *;do COUNT_FILES=$((COUNT_FILES+1));done
MATCHES=$(grep -l "string" * | wc -l)
NON_MATCHES=$((COUNT_FILES - MATCHES))
echo "There are $NON_MATCHES files not matching \"string\""

Lưu ý rằng nó sẽ trả về 1 nếu không có tệp không bị ẩn trong thư mục hiện tại. Bạn cũng có thể muốn bỏ qua các thư mục. Một cách khác để đếm các tập tin và tránh điều kiện cuộc đua sẽ là set -- *, sử dụng $#và lặp với for i do .... Bạn không thể sử dụng wc -lđể đếm các tệp vì tên tệp có thể được tạo thành từ nhiều dòng.
Stéphane Chazelas

0

Tùy thuộc vào số lượng tệp bạn muốn tìm kiếm, đó là một lời khuyên tốt để xem ack-grep . Lý do, vì ack-grepnhanh hơn rất nhiều so với good'ol grepvà CLI gần như giống hệt nhau.

ack-grep -Lur "some string" * | wc -l


0

Với zsh:

( arr=(./*(.N^e_'grep -q PATTERN $REPLY'_)); print ${#arr}; )

Điều này sẽ lưu tên của các tệp không chứa PATTERNtrong một mảng và trả về số lượng phần tử trong mảng. Nó sử dụng vòng loại toàn cầu : .chỉ chọn các tệp thông thường (thêm Dđể bao gồm các tệp ẩn), Nbật null globvà chuỗi phủ định ( ^) e: ^e_'grep -q PATTERN $REPLY'_tiếp tục bỏ chọn các tên tệp mà mã shell giữa các dấu ngoặc kép trả về true.

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.