ฉันต้องการค้นหาไฟล์ทั้งหมดตามความยาวของชื่อไฟล์
ตัวอย่างเช่นถ้าฉันต้องการค้นหาไฟล์ที่มีความยาว 1 เช่นa.go, b.go.
ฉันใส่:
grep '.\{1\}' file
แต่มันไม่ทำงาน ฉันสามารถใช้คำสั่งอะไรเพื่อค้นหาไฟล์ตามความยาวชื่อไฟล์
ฉันต้องการค้นหาไฟล์ทั้งหมดตามความยาวของชื่อไฟล์
ตัวอย่างเช่นถ้าฉันต้องการค้นหาไฟล์ที่มีความยาว 1 เช่นa.go, b.go.
ฉันใส่:
grep '.\{1\}' file
แต่มันไม่ทำงาน ฉันสามารถใช้คำสั่งอะไรเพื่อค้นหาไฟล์ตามความยาวชื่อไฟล์
คำตอบ:
grepค้นหารูปแบบในเนื้อหาของไฟล์ หากคุณต้องการดูชื่อของไฟล์คุณสามารถใช้ shell glob (ถ้าคุณต้องการพิจารณาชื่อไฟล์ในไดเรกทอรีปัจจุบันเท่านั้น):
echo ?.go
(โดยวิธีการมันคือเชลล์ที่ประเมินค่า glob ไม่ใช่echoคำสั่ง)
หากคุณต้องการค้นหาในไดเรกทอรีแบบเรียกซ้ำเริ่มต้นด้วยไดเรกทอรีปัจจุบันเครื่องมือที่ใช้คือfind:
find . -name '?.go'
(โปรดทราบว่าคุณต้องอ้างอิงรูปแบบเพื่อป้องกันเชลล์จากการประเมินว่าเป็นแบบกลมก่อนที่findจะถูกเรียกใช้)
หากคุณต้องการค้นหาชื่อไฟล์คุณสามารถใช้คำสั่งต่อไปนี้:
find -exec basename '{}' ';' | egrep '^.{100,}$'
ที่จะทำงานfindดึงออกชื่อของไฟล์หรือไดเรกทอรีที่ใช้basenameแล้วมองหาชื่อไฟล์หรือชื่อไดเรกทอรีที่มีอย่างน้อย 100 ตัวอักษร หากคุณต้องการที่จะหาชื่อไฟล์ของความยาวที่แน่นอนให้ใช้แทน{100}{100,}
หากคุณต้องการค้นหาชื่อไฟล์รวมถึงเส้นทางทำสิ่งนี้:
find | egrep '/[^/]{100,}$'
นี่จะส่งคืนชื่อไฟล์รวมถึงพา ธ สัมพัทธ์ไปยังตำแหน่งที่คุณรันคำสั่ง find
ก่อนอื่นการgrepค้นหาเนื้อหาของไฟล์มันจะไม่ค้นหาชื่อไฟล์ findสำหรับสิ่งที่คุณต้องการ มันไม่มีตัวเลือกในการตั้งค่าความยาวชื่อไฟล์ แต่คุณสามารถแยกมันออกเพื่อรับสิ่งที่คุณต้องการ นี่คือตัวอย่างบางส่วนที่ฉันเรียกใช้ในไดเรกทอรีที่มีไฟล์ต่อไปนี้:
$ tree
.
├── a
├── ab
├── abc
├── abcd
└── dir
├── a
├── ab
├── abc
└── abcd
การค้นหาไฟล์ในไดเรกทอรีนี้จะคืนค่า:
$ find . -type f | sort
./a
./ab
./abc
./abcd
./dir/a
./dir/ab
./dir/abc
./dir/abcd
ดังนั้นเพื่อค้นหาไฟล์ที่มีความยาว X เราจะต้องลบพา ธ และจับคู่เฉพาะอักขระหลังจากตัวสุดท้าย/:
$ find . -type f | grep -P '/.{3}$'
คำสั่งเพียงแค่เอาsed ./การ-Pเปิดใช้งานการตั้งค่าสถานะเปิดใช้งานการเข้ากันได้ปกติ Perl ที่จำเป็น{n}ซึ่งเป็นสิ่ง PCRE และ$หมายถึง "ตรงกับจุดสิ้นสุดของสตริง"
คุณสามารถทำสิ่งนี้ได้ง่ายๆ:
find . -type f | grep -P '/...$'
ไม่เป็นไรสำหรับตัวเลขขนาดเล็กที่พิมพ์ 15 จุดเพื่อจับคู่ชื่อไฟล์ที่มีความยาว 15 นั้นไม่มีประสิทธิภาพมากนัก
สุดท้ายหากคุณต้องการละเว้นส่วนขยายและจับคู่เฉพาะชื่อไฟล์ให้ทำเช่นนี้ (ตามที่แนะนำ @slm):
find . -type f | grep -P '/.{1}\.'
a.bo.goแต่นี้ยังจะได้พบไฟล์เช่น จะดีกว่าถ้าชื่อไฟล์ของคุณมีมากกว่าหนึ่ง.:
find . -type f | grep -P '/.{1}\.[^.]+$'
หมายเหตุ: วิธีการแก้ปัญหาข้างต้นถือว่าคุณมีชื่อไฟล์ที่ค่อนข้างมีเหตุผลซึ่งไม่มีอักขระบรรทัดใหม่ ฯลฯ และจะนับไม่ละเว้นช่องว่างในชื่อไฟล์เมื่อคำนวณความยาวซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ หากสิ่งเหล่านี้เป็นปัญหาแจ้งให้เราทราบและฉันจะอัปเดตคำตอบของฉัน
คุณไม่ได้ระบุ แต่หากไฟล์อยู่ในโครงสร้างไดเรกทอรีคุณสามารถใช้findเพื่อค้นหาไฟล์ที่มีความยาว 1 ด้วยความช่วยเหลือของgrep:
$ find . -type f | grep -P '/.{1}\.'
$ find . -type f | grep -P '/.{1}\.' | head -10
./util-linux-2.19/include/c.h
./88366/a.bash
./89186/a.bash
./89563/b.txt
./89563/a.txt
./89563/c.txt
./89563/d.txt
./91734/2.c
./91734/4.c
./91734/1.c
ggrep: heystephenwood.com/2013/09/install-gnu-grep-on-mac-osx.html นอกจากนี้ยังตระหนักว่า Q นี้ไม่ได้ติดแท็กเป็น OSX ดังนั้นการใช้grepจึงเหมาะ
ฉันจะใช้สิ่งนี้
find . -type f -name "?.go"
ดังนั้นถ้าคุณใส่สอง "?" จากนั้นคุณกำลังค้นหาชื่อไฟล์ที่มีอักขระสองตัวและนามสกุล
เมื่อคุณต้องการใช้การบีบอัดปกติในคำสั่ง find คุณควรใช้""เช่น:
find /var/log -iname "*.err"
สำหรับกรณีเล็กน้อยใช้:
find yourpath -type f -a -name "?.go"
คุณควรเปลี่ยนเส้นทางที่แท้จริงของคุณกับ yourpath, -aวิธีAnd -type fหมายความว่าคุณเป็นเพียงการมองหาไฟล์ปกติ
? ในแบบสอบถามของคุณหมายถึงตัวอักษรหนึ่งตัวเช่น DOS ถ้าคุณจำได้
ls ?.* ควรให้ผลลัพธ์ที่คุณต้องการ
a.goเป็นชื่อไฟล์ที่มีความยาว 4.aเป็นชื่อไฟล์ของความยาว 1 นี่คือ Unix ไม่ใช่ DOS ที่ชื่อและนามสกุลถูกแยกจากกันและโดยปริยาย.ก็เป็นส่วนหนึ่งของชื่อไฟล์เสมอ