Làm thế nào bạn sẽ đếm mọi lần xuất hiện của một thuật ngữ trong tất cả các tệp trong thư mục hiện tại?


10

Làm thế nào bạn sẽ đếm mọi lần xuất hiện của một thuật ngữ trong tất cả các tệp trong thư mục hiện tại? - và thư mục con (?)

Tôi đã đọc rằng để làm điều này bạn sẽ sử dụng grep; lệnh chính xác là gì?

Ngoài ra, có thể ở trên với một số lệnh khác?

Câu trả lời:


12

Sử dụng grep+ wc(điều này sẽ phục vụ cho nhiều lần xuất hiện của thuật ngữ trên cùng một dòng):

grep -rFo foo | wc -l
  • -rtrong grep: tìm kiếm đệ quy trong hệ thống phân cấp thư mục hiện tại;
  • -Ftrong grep: khớp với một chuỗi cố định thay vì chống lại một mẫu;
  • -otrong grep: chỉ in phù hợp;
  • -ltrong wc: in số đếm của các dòng;
% tree                 
.
├── dir
│   └── file2
└── file1

1 directory, 2 files
% cat file1 
line1 foo foo
line2 foo
line3 foo
% cat dir/file2 
line1 foo foo
line2 foo
line3 foo
% grep -rFo foo | wc -l
8

Tôi nghĩ rằng tốt nhất.
Jacob Vlijm

1
@JacobVlijm Cảm ơn! Tôi cũng thích của bạn (và đã nâng cấp nó rồi)
kos

Tôi nghĩ PCREskhông nên sử dụng vì chúng là thử nghiệm
Edward Torvalds

2
PCRE không phải là "thử nghiệm", nhưng chúng cũng không phải lúc nào cũng được biên dịch thành grep (đó là lý do tại sao tôi sử dụng pcregrep khi tôi cần chúng). Tuy nhiên, trong trường hợp này, chúng không cần thiết, vì câu hỏi hỏi về một "thuật ngữ" có khả năng là một chuỗi cố định, không phải là bất kỳ kiểu nào. Vì vậy, -Fcó lẽ sẽ nhanh hơn.
dannysauer

2
@dannysauer Tôi đã sử dụng PCRE vì một số lý do (sai) tôi nghĩ rằng chúng cần thiết để khớp nhiều lần xuất hiện trên cùng một dòng, nhưng thực sự chúng không phải vậy. Tôi chỉ không thử sử dụng -Fthay vì -P. Cảm ơn lời đề nghị tuyệt vời, cập nhật bằng cách sử dụng -F, mà thực sự phù hợp hơn ở đây.
kos

8

grep -Rc [term] *sẽ làm điều đó. Các -Rlá cờ có nghĩa là bạn muốn đệ quy tìm kiếm thư mục hiện hành và tất cả các thư mục con của nó. Đây *là một bộ chọn tệp có nghĩa: tất cả các tệp. Các -clá cờ làm cho grepsản lượng chỉ số lần xuất hiện. Tuy nhiên, nếu từ xuất hiện nhiều lần trên một dòng, nó chỉ được tính một lần.

Từ man grep:

  -r, --recursive
          Read all files under each directory, recursively, following symbolic links only if they are on the command line.
          This is equivalent to the -d recurse option.

   -R, --dereference-recursive
          Read all files under each directory, recursively.  Follow all symbolic links, unlike -r.

Nếu bạn không có liên kết tượng trưng trong thư mục của bạn, không có sự khác biệt.


bạn có thể thêm -ccờ vào grep. Sau đó, grep tự đếm và bạn không cầnwc
Wayne_Yux 6/11/2015

bạn có thể muốn đặt --trước*
Edward Torvalds

2
Ý *chí chỉ mở rộng thành không phải là dotfiles, vì vậy bạn bỏ lỡ tất cả những thứ đó. Nó có ý nghĩa hơn khi chỉ sử dụng "." vì dù sao bạn cũng sẽ xử lý các đối số theo cách đệ quy - và điều đó sẽ nhận được các tệp chấm. Vấn đề lớn hơn ở đây là điều này sẽ có thể số lượng dòng, không phải số lần xuất hiện của một từ. Nếu thuật ngữ xuất hiện nhiều lần trên một dòng, nó sẽ chỉ được tính một lần bởi "grep -c"
dannysauer

2

Trong một kịch bản python nhỏ:

#!/usr/bin/env python3
import os
import sys

s = sys.argv[1]
n = 0
for root, dirs, files in os.walk(os.getcwd()):
    for f in files:
        f = root+"/"+f      
        try:
            n = n + open(f).read().count(s)
        except:
            pass
print(n)
  • Lưu nó như count_string.py.
  • Chạy nó từ thư mục với lệnh:

    python3 /path/to/count_string.py <term>
    

Ghi chú

  • Nếu thuật ngữ bao gồm khoảng trắng, sử dụng dấu ngoặc kép.
  • Nó đếm mọi lần xuất hiện của thuật ngữ đệ quy, cũng nếu nhiều lần xuất hiện trong một dòng.

Giải trình:

# get the current working directory
currdir = os.getcwd()
# get the term as argument
s = sys.argv[1]
# count occurrences, set start to 0 
n = 0
# use os.walk() to read recursively
for root, dirs, files in os.walk(currdir):
    for f in files:
        # join the path(s) above the file and the file itself
        f = root+"/"+f
        # try to read the file (will fail if the file is unreadable for some reason)
        try:
            # add the number of found occurrences of <term> in the file
            n = n + open(f).read().count(s)
        except:
            pass
print(n)

2
Anh chàng trăn ;) +1
TellMeWhy 6/11/2015

1
btw những gì rootfcho?
TellMeTại sao

1
rootlà đường dẫn đến tệp bao gồm "ở trên" thư mục hiện tại, flà tệp. Ngoài ra, os.path.join()có thể được sử dụng, nhưng dài dòng hơn.
Jacob Vlijm

1
n = n + open(f).read().count(s)?
TellMeTại sao

2
Đây dường như là câu trả lời duy nhất tính tất cả các lần xuất hiện của thuật ngữ như OP yêu cầu. AFAIK, tất cả các giải pháp sử dụng grep sẽ đếm tất cả các dòng mà thuật ngữ xảy ra, do đó, một dòng bao gồm thuật ngữ ba lần sẽ chỉ được tính là một lần xuất hiện.
Joe

2

Là một biến thể của câu trả lời hay của @ kos, nếu bạn quan tâm đến việc ghi rõ số lượng, bạn có thể sử dụng -cchuyển đổi của grep để đếm số lần xuất hiện:

$ grep -rFoc foo
file1:3
dir/file2:3
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.