Mendeteksi pola pada akhir garis dengan grep


65

Jika aku melakukan:

$ ls -R
.:
4Shared/  Cloud/

./4Shared:
UFAIZLV2R7.part3.rar

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

Jika saya ingin daftar .rarfile saja, dan saya menggunakan grep , itu akan menunjukkan kepada saya juga .rar.partfile, apa yang bukan keinginan saya.
Saya memecahkan ini menggunakan findatau ls **/*.rarseperti yang diceritakan di utas ini dan mereka bekerja dengan baik, tapi saya ingin belajar apakah mungkin untuk melakukannya melalui grep.

Saya sudah mencoba (memikirkan EOL):

ls -R | grep ".rar\n"

tanpa hasil.
Saya pikir masalahnya terletak pada menemukan jika greping ditemukan di akhir baris , tetapi saya tidak yakin.

Ada bantuan di sini?


Mengapa Anda ingin menggunakannya grepdalam kasus ini? Mengapa tidak find?
devnull

1
@devnull, mengetahui cara mendeteksi pola yang hanya di akhir baris bisa berguna dalam banyak kasus. Sebagai contoh: portabilitas, penggunaan dalam router dengan Linux yang terlalu sederhana, penggunaan dengan UnxUtils untuk Windows ( findperintahnya bertentangan dengan Windows) dan ... belajar ;-). Pertanyaannya bukan tentang "Daftar File dalam dir" (itu hanya contoh kustom) melainkan "Memahami penggunaan perintah grep"
Sopalajo de Arrierez

1
jujur, jika Anda mengandalkan ujung garis untuk menjadi pemisah Anda, maka Anda harus menggunakannya ls -1R.
mikeserv

1
Dan Anda bahkan tidak perlu grep. Lihat jawaban saya.
mikeserv

@ mikeserv, apa yang bisa terjadi tanpa -1Rsaklar. Ternyata hasilnya sama.
Sopalajo de Arrierez

Jawaban:


89

The $anchor sesuai dengan akhir baris.

ls -R | grep '\.rar$'

Anda juga dapat menggunakan findini:

find . -name '*.rar'

Saya tidak menyadari "." harus lolos grep. Apakah ini diperlakukan sebagai kartu liar?
thebunnyrules

1
@thebunnyrules "." di regex berarti salah satu karakter apa pun.
jordanm

10

Selain pertanyaan Anda, harap perhatikan bahwa .rartidak hanya cocok dengan ".rar" tetapi cocok dengan setiap karakter tunggal (termasuk .) sebelum rar. Dalam hal ini mungkin bukan masalah tetapi .harus melarikan diri dalam regex.

ls -R | grep "\.rar$"

Apakah maksud Anda itu .ascseperti *ascpola? Jadi itu akan cocok, misalnya whereverasc,.
Sopalajo de Arrierez

2
@SopalajodeArrierez Tidak, tidak cocok dengan setiap grup karakter tetapi setiap karakter tunggal, mis xrar.
Hauke ​​Laging

5

Anda juga dapat menginstruksikan grepuntuk mencari string Anda mulai dari batas kata. A .adalah salah satu dari batasan tersebut.

$ ls -R | grep '\brar$'

Contoh

Katakanlah saya punya data sampel ini.

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

Perintah ini hanya akan menemukan file dengan .rarekstensi.

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

Bagaimana ini bekerja?

Metacharacter \badalah jangkar seperti tanda sisipan dan dolar. Ini cocok pada posisi yang disebut "batas kata". Pertandingan ini panjangnya nol.

Situasi di mana ini tidak akan berhasil

Jika Anda memiliki file yang dinamai blah-rarini akan terdeteksi juga.

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

Itu karena karakter selain alfanumerik biasanya dianggap sebagai karakter batas, dan karenanya akan melewati pendekatan ini.


Tampaknya sama pada pandangan pertama, tetapi memang sedikit berbeda. Terima kasih, @slm. Apakah itu mengganggu jika saya menggunakan tanda kutip ganda dan "bukan tanda kutip sederhana?
Sopalajo de Arrierez

1
@SopalajodeArrierez - nggak jalan baik. Ini akan menemukan file yang mungkin dinamai mulai dengan .rar. Tetapi ini tidak akan menjadi masalah dengan penggunaan ls -R. Hanya jika Anda kebetulan menggunakannya ls -Ra.
slm

Apakah salah satu dari Anda tertarik untuk menjelaskan sedikit perbedaan ini kepada publik?
Hauke ​​Laging

@ HaukeLaging -PBeralih ke grepdalam contoh saya. Itu memicu interpretasi PCRE dari argumen tersebut.
slm

1
@SopalajodeArrierez - jika file berisi karakter baris baru ( \n) yang merupakan karakter hukum. The ls -1Rakan memaksa file yang akan ditampilkan dalam satu kolom terlepas.
slm

0

Kerjakan saja :

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

Anda tidak perlu grepsama sekali.

CATATAN: Pekerjaan di atas ... kecuali masih setidaknya afile-rar dan saya tidak mengerti mengapa. Saya akan meninggalkannya di sini, tetapi saya tidak bangga akan hal itu. Bagaimanapun, seperti yang orang lain katakan:

find . '*.rar'

Ini tidak memblokir file yang bernama xraratau afile-rar.
slm

Saya masih mendapatkan file lain di output.
slm

@slm Apa file lain? Saya pikir itu mungkin karena mereka terlalu pendek. Saya hanya memperhatikan itu sendiri. Saya memperbaikinya juga.
mikeserv

File afile-rardan xrarmasih dimasukkan dalam output. Tidak ada perubahan dengan mod terbaru Anda. Masalah sial tidak? Sangat menyenangkan mencoba menyelesaikannya tanpa metode reguler 8-)
slm

@lm Ya, itu sebabnya saya datang ke sini. Saya tidak mengerti mengapa harus -dashmelalui. Hal xraryang bisa saya tangani, tapi bukan -dash.saya yang tidak mengerti-dash.
mikeserv

0

Gunakan tanda kutip tunggal untuk membuat $ berfungsi sebagai end-of-line. Jika Anda juga ingin menggunakan beberapa variabel, gunakan kombinasi tanda kutip ganda dan tunggal seperti di bawah ini:

grep "$var"'$'

Posting saya sebelumnya telah dihapus mengatakan itu rangkap. Izinkan saya menjelaskan bagaimana ini berbeda.

Posting lain menyebutkan penggunaan penuh tanda kutip ganda "", atau penggunaan penuh tanda kutip tunggal ''. Mereka berdua memiliki keterbatasan masing-masing. Mengikuti menjelaskannya.

Masalah dengan semua tanda kutip ganda adalah sebagai berikut: grep "pattern$"memberikan kesalahan berikut:Illegal variable name.

Dan menggunakan semua tanda kutip tunggal berfungsi, tetapi jika Anda ingin substitusi variabel, semua tanda kutip tunggal tidak akan berfungsi. Sebagai contoh:

Jika saya memiliki string A_BOOK, termasuk string lain dalam file FILE.

$ cat FILE
A_BOOK
B_BOOK_NOT_LAST
C_BOOK

Jika saya mengatur BUKU ke variabel BK

set BK = BOOK

Jika saya menerima semua tanda kutip ganda, saya mendapatkan kesalahan berikut grep "${BK}$" FILE*:: $ 1 untuk substitusi variabel, 2 untuk akhir pola ( nama variabel ilegal ).

Jika saya menerima semua tanda kutip, subtitusi variabel tidak terjadi. grep '${BK}$' FILEtidak mengembalikan apa pun

Jika saya menggunakan kombinasi tanda kutip ganda dan tunggal, saya mendapatkan apa yang saya harapkan. Kutipan ganda untuk substitusi variabel, dan tanda kutip tunggal untuk akhir pola.

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

Sepertinya Anda menggunakan csh. The "foo$"sintaks bekerja dengan baik pada sh dan keluarga.
Olorin

Ya, Olorin. Saya menggunakan tcsh. Terima kasih telah menunjukkan itu.
user274900

0

Jika setelah mengikuti hal di atas dan tidak ada yang berhasil, itu mungkin karena akhir baris. Untuk memperbaiki, lakukan: dos2unix pr0n.txtdan lakukan greplagi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.