ฉันต้องการค้นหาไฟล์ทั้งหมดตามความยาวของชื่อไฟล์
ตัวอย่างเช่นถ้าฉันต้องการค้นหาไฟล์ที่มีความยาว 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 ที่ชื่อและนามสกุลถูกแยกจากกันและโดยปริยาย.
ก็เป็นส่วนหนึ่งของชื่อไฟล์เสมอ