Phát hiện mẫu ở cuối dòng với grep


65

Nếu tôi làm:

$ ls -R
.:
4Shared/  Cloud/

./4Shared:
UFAIZLV2R7.part3.rar

./Cloud:
UFAIZLV2R7.part2.rar.part
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part4.rar.part

Nếu tôi chỉ muốn liệt kê các .rartệp và tôi sử dụng grep , nó cũng sẽ hiển thị cho tôi các .rar.parttệp, đó không phải là mong muốn của tôi.
Tôi đang giải quyết điều này bằng cách sử dụng findhoặc ls **/*.rarnhư đã nói trong chủ đề này và chúng hoạt động tốt, nhưng tôi muốn tìm hiểu nếu có thể thực hiện được thông qua grep.

Tôi đã thử (nghĩ về EOL):

ls -R | grep ".rar\n"

không có kết quả.
Tôi nghĩ rằng vấn đề nằm ở việc khám phá nếu tìm thấy greping ở cuối dòng , nhưng tôi không chắc chắn.

Có ai giúp đỡ ở đây không?


Tại sao bạn muốn sử dụng greptrong trường hợp này? Tại sao không find?
devnull

1
@devnull, biết cách phát hiện các mẫu chỉ ở cuối dòng có thể hữu ích trong nhiều trường hợp. Ví dụ: tính di động, việc sử dụng trong các bộ định tuyến với Linux quá đơn giản, sử dụng với UnxUtils cho Windows ( findlệnh của nó mâu thuẫn với Windows) và ... học ;-). Câu hỏi không phải là về "Liệt kê các tệp trong thư mục" (đó chỉ là một ví dụ tùy chỉnh) mà là "Tìm hiểu cách sử dụng lệnh grep"
Sopalajo de Arrierez

1
Thành thật mà nói, nếu bạn đang tính đến cuối dòng là dấu phân cách của bạn, thì bạn nên sử dụng ls -1R.
mikeerv

1
Và bạn thậm chí không cần grep. Xem câu trả lời của tôi.
mikeerv

@mikeerv, những gì có thể xảy ra mà không có công -1Rtắc. Rõ ràng kết quả là như nhau.
Sopalajo de Arrierez

Câu trả lời:


89

Các $neo phù hợp với kết thúc của một dòng.

ls -R | grep '\.rar$'

Bạn cũng có thể sử dụng findcho việc này:

find . -name '*.rar'

Tôi đã không nhận ra "." cần phải được trốn thoát trong grep. Có được coi là một thẻ hoang dã?
thebunnyrules

1
@thebunnyrules "." trong regex có nghĩa là một trong bất kỳ nhân vật.
jordanm

10

Ngoài câu hỏi của bạn, xin lưu ý rằng .rarkhông chỉ khớp với ".rar" mà còn khớp với mọi ký tự đơn (bao gồm .) trước rar. Trong trường hợp này có lẽ không phải là một vấn đề nhưng .phải được thoát trong regexes.

ls -R | grep "\.rar$"

Ý bạn .asclà giống như *ascmẫu? Vì vậy, nó sẽ phù hợp, ví dụ , whereverasc.
Sopalajo de Arrierez

2
@SopalajodeArrierez Không, nó không phù hợp với mọi nhóm nhân vật mà là mọi nhân vật, vd xrar.
Hauke ​​Laging

5

Bạn cũng có thể hướng dẫn greptìm chuỗi của bạn bắt đầu từ một ranh giới từ. A .là một trong những ranh giới như vậy.

$ ls -R | grep '\brar$'

Thí dụ

Nói rằng tôi có dữ liệu mẫu này.

$ ls -1
afile.rar
xrar
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part2.rar.part

Lệnh này sẽ chỉ tìm thấy các tập tin với .rarphần mở rộng.

$ ls -R | grep '\brar$'
afile.rar

Làm thế nào điều này hoạt động?

Các metacharacter \blà một mỏ neo như dấu mũ và ký hiệu đô la. Nó phù hợp tại một vị trí được gọi là "ranh giới từ". Trận đấu này có độ dài bằng không.

Tình huống này sẽ không hoạt động

Nếu bạn có tập tin được đặt tên, blah-rarchúng cũng sẽ được phát hiện.

$ ls -R | grep '\brar$'
afile-rar
afile.rar

Đó là bởi vì các ký tự không phải là chữ và số thường được coi là ký tự ranh giới và do đó sẽ vượt qua phương pháp này.


Có vẻ giống nhau từ cái nhìn đầu tiên, nhưng nó hơi khác nhau, thực sự. Cảm ơn, @slm. Có phiền không nếu tôi sử dụng dấu ngoặc kép "thay vì dấu ngoặc đơn giản?
Sopalajo de Arrierez

1
@SopalajodeArrierez - không hoạt động theo cách nào. Điều này sẽ tìm thấy bất kỳ tập tin có thể được đặt tên bắt đầu w / .rar. Nhưng những điều này sẽ không phải là một vấn đề với việc sử dụng ls -R. Chỉ khi bạn tình cờ sử dụng ls -Ra.
slm

Một trong số các bạn có quan tâm đến việc giải thích sự khác biệt nhỏ này với công chúng không?
Hauke ​​Laging

@HaukeLaging Việc -Pchuyển sang greptrong ví dụ của tôi. Điều đó kích hoạt giải thích PCRE của đối số.
slm

1
@SopalajodeArrierez - nếu một tệp chứa ký tự dòng mới ( \n) là ký tự hợp pháp. Các ls -1Rsẽ buộc các tập tin được hiển thị trong một cột duy nhất không phân biệt.
slm

0

Cứ làm đi :

ls -1R -I"?" -I"??" -I"???" -I"*[!.][!r][!a][!r]"

Bạn không cần grepgì cả.

LƯU Ý: Các công việc trên ... ngoại trừ nó vẫn nhận được ít nhất afile-rar và tôi không hiểu tại sao. Tôi sẽ để nó ở đây, nhưng tôi không tự hào về nó. Trong mọi trường hợp, như những người khác đã nói:

find . '*.rar'

Điều này đã không chặn các tập tin có tên xrarhoặc afile-rar.
slm

Tôi vẫn nhận được các tập tin khác trong đầu ra.
slm

@slm Tập tin nào khác? Tôi nghĩ rằng nó có thể là do chúng quá ngắn. Tôi chỉ nhận thấy rằng bản thân mình. Tôi cũng sửa nó.
mikeerv

Các tập tin afile-rarxrarvẫn đang được bao gồm trong đầu ra. Không có thay đổi với mod mới nhất của bạn. Vấn đề khó khăn không? Thật thú vị khi cố gắng giải quyết nó mà không cần các phương pháp thông thường 8-)
slm

@slm Vâng, đó là lý do tại sao tôi đến đây. Tôi không hiểu tại sao lại -dashvượt qua. Các xrarđiều tôi có thể xử lý, nhưng không phải là -dash.tôi không hiểu được-dash.
mikeserv

0

Sử dụng dấu ngoặc đơn để làm cho công việc $ là kết thúc. Nếu bạn cũng muốn grep với một số biến, hãy sử dụng kết hợp dấu ngoặc kép và dấu ngoặc đơn như dưới đây:

grep "$var"'$'

Bài viết trước của tôi đã bị xóa nói rằng nó là trùng lặp. Hãy để tôi giải thích điều này khác nhau như thế nào.

Các bài viết khác đề cập đến việc sử dụng đầy đủ các dấu ngoặc kép ""hoặc sử dụng đầy đủ các dấu ngoặc đơn ''. Cả hai đều có những hạn chế riêng. Sau đây giải thích nó.

Vấn đề với tất cả các dấu ngoặc kép là sau: grep "pattern$"đưa ra lỗi sau:Illegal variable name.

Và sử dụng tất cả các dấu ngoặc đơn hoạt động, nhưng nếu bạn muốn thay thế biến, tất cả các dấu ngoặc đơn sẽ không hoạt động. Ví dụ:

Nếu tôi có chuỗi A_BOOK, bao gồm các chuỗi khác trong tệp TẬP TIN.

$ cat FILE
A_BOOK
B_BOOK_NOT_LAST
C_BOOK

Nếu tôi đặt BOOK thành một biến BK

set BK = BOOK

Nếu tôi grep với tất cả các dấu ngoặc kép, tôi nhận được lỗi sau grep "${BK}$" FILE*:: 1st $ cho thay thế biến, thứ 2 cho cuối mẫu ( Tên biến bất hợp pháp ).

Nếu tôi grep với tất cả các dấu ngoặc đơn, sự thay thế biến không xảy ra. grep '${BK}$' FILEtrả lại không có gì

Nếu tôi sử dụng kết hợp các trích dẫn kép và đơn, tôi sẽ nhận được những gì tôi mong đợi. Dấu ngoặc kép để thay thế biến, và dấu ngoặc đơn cho cuối mẫu.

$ grep "${BK}"'$'  # << gives expected output
A_BOOK
C_BOOK

Có vẻ như bạn đang sử dụng csh. Các "foo$"cú pháp hoạt động tốt trên sh và gia đình.
Olorin

Có Olorin. Tôi đang sử dụng tcsh. Cảm ơn đã chỉ ra rằng.
dùng274900

0

Nếu sau khi làm theo những điều trên và không có gì hoạt động, nó có thể là do kết thúc dòng. Để sửa chữa, làm: dos2unix pr0n.txtvà làm greplại của bạn .

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.