Làm cách nào để tìm ra các tệp trong thư mục hiện tại không chứa từ foo
(đang sử dụng grep
)?
Làm cách nào để tìm ra các tệp trong thư mục hiện tại không chứa từ foo
(đang sử dụng grep
)?
Câu trả lời:
Nếu grep của bạn có tùy chọn -L
(hoặc --files-without-match
):
$ grep -L "foo" *
GREP_OPTIONS='--exclude-dir=.svn --exclude-dir=.git'
: ^)
-rL
thay vì -L
khớp với các thư mục con
grep -L 'foo' -- *
Tiêu chuẩn là các lệnh có các tùy chọn dài sử dụng --
để chỉ ra rằng không có thêm tùy chọn nào sau thời điểm này.
Hãy nhìn vào ack
. Nó .svn
tự động loại trừ cho bạn, cung cấp cho bạn các biểu thức chính quy Perl và là một bản tải xuống đơn giản của một chương trình Perl.
Tương đương với những gì bạn đang tìm kiếm nên có, trong ack
:
ack -L foo
Bạn có thể làm điều đó với grep một mình (mà không tìm thấy).
grep -riL "foo" .
Đây là giải thích về các tham số được sử dụng trên grep
-L, --files-without-match
each file processed.
-R, -r, --recursive
Recursively search subdirectories listed.
-i, --ignore-case
Perform case insensitive matching.
Nếu bạn sử dụng l
(hạ cấp), bạn sẽ nhận được điều ngược lại (các tệp có kết quả khớp)
-l, --files-with-matches
Only the names of files containing selected lines are written
Lệnh sau cung cấp cho tôi tất cả các tệp không chứa mẫu foo
:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep 0
grep '0$'
cũng sẽ khớp các tệp với bội số của 10 dòng! Bạn cần grep ':0$'
ở cuối để kiểm tra rõ ràng ': 0' ở cuối dòng. Sau đó, bạn sẽ chỉ nhận được các tập tin có dòng không khớp.
Lệnh sau không bao gồm nhu cầu tìm kiếm để lọc các svn
thư mục bằng cách sử dụng giây grep
.
grep -rL "foo" ./* | grep -v "\.svn"
Bạn thực sự sẽ cần:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep :0\$
Vấn đề
Tôi cần cấu trúc lại một dự án lớn sử dụng .phtml
các tệp để viết HTML bằng mã PHP nội tuyến. Tôi muốn sử dụng các mẫu Mustache thay thế. Tôi muốn tìm bất kỳ .phtml
giles nào không chứa chuỗi new Mustache
vì chúng vẫn cần phải viết lại.
Giải pháp
find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
Giải trình
Trước các đường ống:
Tìm thấy
find .
Tìm tệp đệ quy, bắt đầu trong thư mục này
-iname '*.phtml'
Tên tệp phải chứa .phtml
( i
làm cho nó không phân biệt chữ hoa chữ thường)
-exec 'grep -H -E -o -c 'new Mustache' {}'
Chạy grep
lệnh trên mỗi đường dẫn phù hợp
Grep
-H
Luôn in các tiêu đề tên tệp với các dòng đầu ra.
-E
Mẫu diễn giải như một biểu thức chính quy mở rộng (tức là buộc grep hành xử như egrep).
-o
Chỉ in phần phù hợp của các dòng.
-c
Chỉ có một số dòng được chọn được ghi vào đầu ra tiêu chuẩn.
Điều này sẽ cho tôi một danh sách tất cả các đường dẫn tệp kết thúc .phtml
bằng số đếm số lần chuỗi new Mustache
xảy ra trong mỗi đường dẫn.
$> find . -iname '*.phtml$' -exec 'grep -H -E -o -c 'new Mustache' {}'\;
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/orders.phtml:1
./app/MyApp/Customer/View/Account/banking.phtml:1
./app/MyApp/Customer/View/Account/applycomplete.phtml:1
./app/MyApp/Customer/View/Account/catalogue.phtml:1
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0
Ống đầu tiên grep :0$
lọc danh sách này chỉ bao gồm các dòng kết thúc bằng :0
:
$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0
Ống thứ hai sed 's/..$//'
loại bỏ hai ký tự cuối cùng của mỗi dòng, chỉ để lại các đường dẫn tệp.
$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml
./app/MyApp/Customer/View/Account/studio.phtml
./app/MyApp/Customer/View/Account/classadd.phtml
./app/MyApp/Customer/View/Account/orders-trade.phtml
Grep của tôi không có tùy chọn -L. Tôi tìm cách giải quyết để đạt được điều này.
Các ý tưởng là:
tạo sự khác biệt giữa 2 tệp kết xuất với lệnh diff.
grep 'foo' *.log | cut -c1-14 | uniq > txt1.txt
grep * *.log | cut -c1-14 | uniq > txt2.txt
diff txt1.txt txt2.txt | grep ">"
diff
giữa hai luồng đầu ra (tôi nghĩ rằng bạn bao quanh các lệnh bằng dấu ngoặc đơn và cũng có một khung góc ở đó ở đâu đó), nếu hệ thống của bạn hỗ trợ nó, tôi đoán vậy là câu hỏi, vì nó không hỗ trợgrep -L
find *20161109* -mtime -2|grep -vwE "(TRIGGER)"
Bạn có thể chỉ định bộ lọc trong "tìm" và chuỗi loại trừ trong "grep -vwE". Sử dụng mtime dưới find nếu bạn cũng cần lọc theo thời gian đã sửa đổi.
Theo nhận xét của @tukan, có một báo cáo lỗi mở cho Ag liên quan đến -L
/ --files-without-matches
cờ:
Vì có ít tiến triển trong báo cáo lỗi, không nên dựa vào-L
tùy chọn được đề cập dưới đây , miễn là lỗi chưa được giải quyết. Sử dụng các phương pháp khác nhau được trình bày trong chủ đề này thay thế. Trích dẫn một bình luận cho báo cáo lỗi [nhấn mạnh của tôi]:
Bất kỳ cập nhật về điều này?
-L
hoàn toàn bỏ qua các trận đấu trên dòng đầu tiên của tập tin. Có vẻ như nếu điều này sẽ không được khắc phục sớm, cờ sẽ bị xóa hoàn toàn, vì nó thực sự không hoạt động như quảng cáo .
Để thay thế mạnh mẽ grep
, bạn có thể sử dụng Trình tìm kiếm bạc - Ag :
Một công cụ tìm kiếm mã tương tự như ack, tập trung vào tốc độ.
Nhìn vào man ag
, chúng tôi tìm thấy -L
hoặc --files-without-matches
tùy chọn:
... OPTIONS ... -L --files-without-matches Only print the names of files that don´t contain matches.
Tức là, để tìm kiếm đệ quy các tệp không khớp foo
, từ thư mục hiện tại:
ag -L foo
Để chỉ tìm kiếm thư mục hiện tại cho các tệp không khớp foo
, chỉ cần chỉ định --depth=0
cho đệ quy:
ag -L foo --depth 0
-L
lỗi - github.com/ggreer/the_silver_searcher/issues/238
grep -irnw "filepath" -ve "pattern"
hoặc là
grep -ve "pattern" < file
Lệnh trên sẽ cho chúng ta kết quả khi -v tìm thấy nghịch đảo của mẫu đang được tìm kiếm
-l
tùy chọn để chỉ in tên tệp; nhưng điều này vẫn in tên của bất kỳ tệp nào chứa bất kỳ dòng nào không chứa mẫu. Tôi tin rằng OP muốn tìm các tệp không chứa bất kỳ dòng nào chứa mẫu.
Lệnh sau có thể giúp bạn lọc các dòng bao gồm chuỗi con "foo".
cat file | grep -v "foo"
cat
.