การตรวจจับลวดลายที่ส่วนท้ายของบรรทัดด้วย grep


64

ถ้าฉันทำ:

$ ls -R
.:
4Shared/  Cloud/

./4Shared:
UFAIZLV2R7.part3.rar

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

ถ้าฉันต้องการแสดงรายการ.rarไฟล์เท่านั้นและฉันใช้grepมันจะแสดง.rar.partไฟล์ให้ฉันด้วยเช่นกันสิ่งที่ฉันไม่ต้องการ
ฉันกำลังแก้นี้โดยใช้findหรือls **/*.rarที่บอกในหัวข้อนี้และพวกเขาทำงานได้ดี grepแต่ผมอยากจะเรียนรู้ว่ามันเป็นไปได้ที่จะทำมันผ่าน

ฉันลองแล้ว (กำลังคิดEOL):

ls -R | grep ".rar\n"

โดยไม่มีผลลัพธ์
ฉันคิดว่าปัญหาอยู่ที่การค้นพบว่าพบ greping ที่ส่วนท้ายของบรรทัดแต่ฉันไม่แน่ใจ

มีอะไรช่วยด้วยมั้ย


เหตุใดคุณต้องการใช้grepในกรณีนี้ ทำไมไม่find?
devnull

1
@devnull การรู้วิธีตรวจจับรูปแบบที่ท้ายบรรทัดอาจเป็นประโยชน์ในหลายกรณี ตัวอย่างเช่น: การพกพา, การใช้งานในเราเตอร์ที่ฝังตัวลินุกซ์ที่ง่ายเกินไป, การใช้ UnxUtils สำหรับ Windows ( findคำสั่งขัดแย้งกับ Windows หนึ่ง) และ ... learning ;-) คำถามไม่ได้เกี่ยวกับ "การแสดงไฟล์ใน dir" (นั่นเป็นเพียงตัวอย่างที่กำหนดเอง) แต่ "การทำความเข้าใจการใช้คำสั่ง grep"
Sopalajo de Arrierez

1
ls -1Rตรงไปตรงมาถ้าคุณกำลังนับที่ท้ายบรรทัดที่จะคั่นของคุณแล้วคุณควรจะใช้
mikeserv

1
grepและคุณไม่จำเป็นต้อง ดูคำตอบของฉัน
mikeserv

@mikeserv สิ่งที่อาจเกิดขึ้นได้หากไม่มี-1Rสวิตช์ เห็นได้ชัดว่าผลลัพธ์เหมือนกัน
Sopalajo de Arrierez

คำตอบ:


88

$สมอตรงปลายของเส้น

ls -R | grep '\.rar$'

คุณยังสามารถใช้findสำหรับสิ่งนี้:

find . -name '*.rar'

ฉันไม่ได้ตระหนักถึง "." จะต้องมีการหลบหนีใน grep ถือว่าเป็นไวลด์การ์ดหรือไม่?
thebunnyrules

1
@thebunnyrules "." ใน regex หมายถึงหนึ่งในตัวละครใด ๆ
จอร์แดน

10

นอกเหนือไปจากคำถามของคุณโปรดทราบว่า.rarไม่เพียง แต่ตรงกับ ".rar" แต่ตรงกับตัวละครทุกตัวเดียว (รวม.) rarก่อน ในกรณีนี้อาจไม่ใช่ปัญหา แต่.ต้องหลบหนีใน regexes

ls -R | grep "\.rar$"

คุณหมายถึงว่า.ascเป็นเหมือน*ascรูปแบบหรือไม่ whereverascดังนั้นมันจะตรงกับตัวอย่างเช่น
Sopalajo de Arrierez

2
@SopalajodeArrierez ไม่มีก็ไม่ตรงกับทุกกลุ่มของตัวละคร xrarแต่ทุกตัวเดียวเช่น
Hauke ​​Laging

5

คุณยังสามารถแนะนำgrepให้ค้นหาสตริงของคุณโดยเริ่มจากขอบเขตของคำ A .เป็นหนึ่งในขอบเขตดังกล่าว

$ ls -R | grep '\brar$'

ตัวอย่าง

สมมติว่าฉันมีข้อมูลตัวอย่างนี้

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

คำสั่งนี้จะค้นหาเฉพาะไฟล์ที่มี.rarนามสกุล

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

มันทำงานอย่างไร

metacharacter \bเป็นจุดยึดเช่นเครื่องหมายรูปหมวกและเครื่องหมายดอลลาร์ มันตรงกับตำแหน่งที่เรียกว่า "ขอบเขตของคำ" การแข่งขันนี้มีความยาวเป็นศูนย์

สถานการณ์ที่สิ่งนี้ไม่ทำงาน

หากคุณมีไฟล์ที่ชื่อไฟล์blah-rarเหล่านี้ก็จะถูกตรวจจับเช่นกัน

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

นั่นเป็นเพราะตัวละครอื่น ๆ นอกเหนือจากตัวอักษรและตัวเลขมักจะถือว่าเป็นตัวละครที่มีขอบเขตและดังนั้นจะลื่นผ่านวิธีนี้


ดูเหมือนว่าจะเหมือนกันตั้งแต่แรกเห็น แต่มันแตกต่างกันเล็กน้อยแน่นอน ขอบคุณ @slm จะรำคาญไหมถ้าฉันใช้เครื่องหมายคำพูดคู่"แทนคำพูดธรรมดา?
Sopalajo de Arrierez

1
@SopalajodeArrierez - ไม่ทำงานอย่างใดอย่างหนึ่ง นี้จะหาไฟล์ใด ๆ ที่อาจจะมีชื่อเริ่มต้น w .rar/ ls -Rแต่เหล่านี้จะไม่เป็นปัญหากับการใช้งานของ ls -Raเฉพาะในกรณีที่คุณเกิดขึ้นที่จะใช้
slm

คุณหนึ่งคนสนใจที่จะอธิบายความแตกต่างเล็กน้อยนี้ให้กับสาธารณะหรือไม่
Hauke ​​Laging

@HaukeLaging -Pสวิตช์ไปgrepในตัวอย่างของฉัน นั่นทำให้เกิดการตีความแบบ PCRE ของการโต้แย้ง
slm

1
@SopalajodeArrierez - หากไฟล์มีอักขระขึ้นบรรทัดใหม่ ( \n) ซึ่งเป็นอักขระที่ถูกกฎหมาย ls -1Rจะบังคับให้ไฟล์ที่จะแสดงในคอลัมน์เดียวโดยไม่คำนึงถึง
slm

0

แค่ทำ :

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

คุณไม่ต้องการgrepเลย

หมายเหตุ:งานข้างต้น ... ยกเว้นอย่างน้อย ก็ยังได้รับafile-rarและฉันไม่เข้าใจว่าทำไม ฉันจะทิ้งไว้ที่นี่ แต่ฉันไม่ภูมิใจ ในกรณีใด ๆ ตามที่คนอื่นพูด:

find . '*.rar'

เรื่องนี้ไม่ได้ป้องกันการตั้งชื่อไฟล์หรือxrar afile-rar
slm

ฉันยังคงได้รับไฟล์อื่น ๆ ในผลลัพธ์
slm

@slm ไฟล์อื่น ๆ คืออะไร? ฉันคิดว่าอาจเป็นเพราะพวกเขาสั้นเกินไป ฉันเพิ่งสังเกตเห็นว่าตัวเอง ฉันแก้ไขมันด้วย
mikeserv

ไฟล์afile-rarและxrarยังคงถูกรวมอยู่ในเอาท์พุท ไม่มีการเปลี่ยนแปลงกับ mods ล่าสุดของคุณเช่นกัน ปัญหาน่ารำคาญใช่ไหม มันสนุกที่จะพยายามแก้มันโดยไม่ใช้วิธีปกติ 8-)
slm

@slm ใช่มันเป็นเหตุผลที่ฉันมาที่นี่ ฉันไม่เข้าใจว่าทำไมถึง-dashผ่าน xrarสิ่งที่ฉันสามารถจัดการ แต่ไม่ได้-dash.ฉันไม่เข้าใจ-dash.
mikeserv

0

ใช้เครื่องหมายคำพูดเดี่ยวเพื่อให้ $ ทำงานเป็นจุดสิ้นสุดของบรรทัด หากคุณต้องการ grep พร้อมกับตัวแปรบางตัวให้ใช้การรวมกันของเครื่องหมายคำพูดคู่และเดี่ยวดังนี้:

grep "$var"'$'

โพสต์ก่อนหน้าของฉันถูกลบโดยบอกว่ามันซ้ำซ้อน ผมขออธิบายว่ามันแตกต่างกันอย่างไร

โพสต์อื่น ๆ ที่พูดถึงการใช้งานทั้งเต็มไปด้วยคำพูดสองหรือการใช้งานเต็มรูปแบบของราคาเดียว"" ''พวกเขาทั้งสองมีข้อ จำกัด ของตัวเอง ต่อไปนี้จะอธิบายมัน

ปัญหาเกี่ยวกับเครื่องหมายคำพูดคู่ทั้งหมดต่อไปนี้: grep "pattern$"ให้ข้อผิดพลาดต่อไปนี้:Illegal variable name.

และการใช้อัญประกาศเดี่ยวทั้งหมดใช้ได้ แต่ถ้าคุณต้องการการแทนที่ตัวแปรอัญประกาศเดี่ยวทั้งหมดจะไม่ทำงาน ตัวอย่างเช่น:

ถ้าฉันมีสตริงA_BOOKรวมถึงสตริงอื่น ๆ ในไฟล์ FILE

$ cat FILE
A_BOOK
B_BOOK_NOT_LAST
C_BOOK

ถ้าฉันตั้งค่า BOOK ให้เป็นตัวแปร BK

set BK = BOOK

หากฉัน grep พร้อมเครื่องหมายคำพูดคู่ทั้งหมดฉันจะได้รับข้อผิดพลาดต่อไปนี้grep "${BK}$" FILE*:: $ 1 สำหรับการทดแทนตัวแปรอันดับที่ 2 สำหรับการสิ้นสุดของรูปแบบ ( ชื่อตัวแปรผิดกฎหมาย )

หากฉัน grep ด้วยเครื่องหมายคำพูดเดี่ยวทั้งหมดการทดแทนตัวแปรจะไม่เกิดขึ้น grep '${BK}$' FILEไม่มีอะไรคืน

หากฉันใช้การผสมผสานของคำพูดสองคำและเดี่ยวฉันจะได้รับสิ่งที่ฉันคาดหวัง เครื่องหมายคำพูดคู่สำหรับการทดแทนตัวแปรและเครื่องหมายคำพูดเดี่ยวสำหรับจุดสิ้นสุดของรูปแบบ

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

ดูเหมือนว่าคุณกำลังใช้ csh "foo$"ไวยากรณ์ทำงานได้ดีในการดวลจุดโทษและครอบครัว
Olorin

ใช่ Olorin ฉันกำลังใช้ tcsh ขอบคุณสำหรับการชี้ว่า
274900

0

หากหลังจากทำตามข้างต้นแล้วและไม่มีอะไรทำงานอาจเป็นเพราะการสิ้นสุดของบรรทัด ในการแก้ไขให้ทำ: dos2unix pr0n.txtและทำgrepอีกครั้ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.