คำสั่ง find ใน Linux shell ให้คุณค้นหาไฟล์ในระบบไฟล์ สามารถหาไฟล์ได้จากชื่อ สิทธิ์ผู้ใช้ และขนาด คำสั่ง find ยังสามารถดำเนินการกับไฟล์ที่พบได้อีกด้วย
ไวยากรณ์คำสั่ง Find
ไวยากรณ์สำหรับคำสั่ง find มีดังนี้:
find [OPTIONS] [PATH] [EXPRESSION]
โดยที่:
- [OPTIONS] คือตัวเลือกจากตารางด้านล่างเพื่อกำหนดพฤติกรรมของ find
- [PATH] คือจุดเริ่มต้นสำหรับการค้นหา
- [EXPRESSION] กำหนดเงื่อนไขค้นหาไฟล์ที่ตรงกัน และการกระทำที่ควรทำกับไฟล์ที่พบ
ตัวเลือก (Options)
นี่คือ OPTIONS ที่ใช้บ่อยสำหรับคำสั่ง find ปรับจากคู่มือ:
| -P | ไม่ติดตาม symbolic links นี่คือพฤติกรรมเริ่มต้น |
| -L | ติดตาม symbolic links เมื่อ find ตรวจสอบหรือพิมพ์ข้อมูลไฟล์ ข้อมูลที่ใช้จะมาจากคุณสมบัติของไฟล์ที่ link ชี้ ไม่ใช่จาก link เอง |
| -H | ไม่ติดตาม symbolic links ยกเว้นขณะประมวลผลอาร์กิวเมนต์บรรทัดคำสั่ง |
นิพจน์ (Expressions)
นี่คือบางสเตทเมนต์ทั่วไปจากคู่มือ find ที่ใช้สร้าง EXPRESSION ซึ่งทดสอบไฟล์ที่ตรงกันและเลือกทำการกระทำ:
| Tests (เงื่อนไขค้นหา) | |
|---|---|
| -empty | หาไฟล์ว่าง |
| -executable | จับคู่ไฟล์ที่ execute ได้ และไดเรกทอรีที่ search ได้ |
| -group name | ไฟล์เป็นของกลุ่มที่มี name |
| -mtime n | ข้อมูลไฟล์ถูกแก้ไขล่าสุด น้อยกว่า มากกว่า หรือเท่ากับ n*24 ชั่วโมงที่แล้ว |
| -name pattern | ฐานของชื่อไฟล์ (path นำไดเรกทอรีนำหน้าออก) ตรงกับ pattern pattern |
| -path pattern | path ของไฟล์ตรงกับ pattern pattern |
| -readable | จับคู่ไฟล์ที่ user ปัจจุบันอ่านได้ |
| -size n | ไฟล์ใช้พื้นที่ น้อยกว่า มากกว่า หรือเท่ากับ n หน่วย ปัดขึ้น (ดูตารางด้านล่างสำหรับหน่วยที่ใช้ได้) |
| -type c | ไฟล์เป็นประเภท c (ดูตารางด้านล่างสำหรับค่า c) |
| -user name | ไฟล์เป็นของ user name |
| Actions (การกระทำ) | |
|---|---|
| แสดงชื่อไฟล์ (default action) | |
| -prune | ถ้าไฟล์เป็น directory อย่าลงไปลึกในมัน |
| -depth | ประมวลผลเนื้อหาแต่ละ directory ก่อน directory เอง |
| -delete | ลบไฟล์ที่ตรงกัน -delete ยังทำงานเหมือน option (เพราะ imply -depth) |
| -exec command | execute command |
| -execdir command | เหมือน -exec แต่รันคำสั่งจาก subdirectory ที่มีไฟล์ที่ตรงกัน |
| -ok command | เหมือน -exec แต่ถามผู้ใช้ก่อน |
| -okdir command | เหมือน -execdir แต่ถามผู้ใช้ก่อนเหมือน -ok |
| -printf format | พิมพ์รายละเอียดไฟล์ใน format |
ตัวดำเนินการในนิพจน์ (Operators in Expressions)
ตัวดำเนินการสามารถใช้เชื่อมรายการในนิพจน์ได้:
| -o | OR |
| -a | AND (default operator ระหว่างนิพจน์เมื่อไม่มี operator) |
สำหรับรายการตัวเลือกและนิพจน์ครบถ้วน สามารถรันได้:
man find
ตัวอย่างคำสั่ง Find
Options, expressions และ actions สามารถรวมกันได้ เพื่อสร้างการค้นหาง่ายๆ รายการไฟล์ที่ตรงกัน หรือการดำเนินการซับซ้อนที่ค้นหาไฟล์ด้วยเงื่อนไขซับซ้อนและดำเนินการ ดูตัวอย่างด้านล่าง:
ค้นหาไฟล์ด้วยชื่อไฟล์
ตัวอย่างนี้หาไฟล์ทุกไฟล์ชื่อ myfile ในไดเรกทอรี /home/screw:
find /home/screw -name myfile
ค้นหาตามประเภท (Type)
คำสั่งข้างต้นจะคืนไฟล์ที่ตรงทั้งหมด – รวมถึง directories, links, และ devices – ทุกอย่างใน filesystem
นิพจน์ -type f จำกัดการค้นหาเฉพาะ ไฟล์ เท่านั้น เพื่อค้นหาไฟล์ชื่อ myfile:
find /home/screw -type f -name myfile
หรือ ค้นหาเฉพาะ directories:
find /home/screw -type d -name myfile
ประเภทที่มีอยู่:
| b | Block (buffered) special |
| c | Character (unbuffered) special |
| d | Directory |
| p | Named pipe (FIFO) |
| f | Regular file |
| l | Symbolic link; ไม่เป็นจริงหาก -L หรือ -follow อยู่ในผลกระทบ ยกเว้น link ชำรุด |
| s | Socket |
Case Sensitivity
ตัวเลือก -name เป็น case sensitive – เพื่อค้นหาไม่สนใจ case ใช้ -iname:
find /home/screw -iname mYFiLe
ค้นหาไฟล์ด้วยนามสกุลใช้ Wildcards & Regex
คุณสามารถใช้ wildcards (*) ในชื่อไฟล์ เพื่อค้นหาตามนามสกุล:
find -L /home/screw -name '*.pdf'
ข้างต้นจะค้นหาไฟล์ทุกไฟล์ที่มีนามสกุล .pdf รูปแบบค้นหาที่มีเครื่องหมายคำพูดสามารถมี regex ได้
ข้ามไฟล์ตามชื่อหรือนามสกุล
ตัวดำเนินการ -not ใช้ข้ามไฟล์ตามชื่อหรือ pattern คืนค่าผลลัพธ์ทั้งหมดที่ไม่ตรง:
find /home/screw -type f -not -name '*.pdf'
ข้ามไดเรกทอรีทั้งหมดจากผลลัพธ์
ใช้ตัวเลือก -prune เพื่อข้าม path ที่ตรงและเนื้อหาในมัน ตัวอย่างข้างล่างจะข้ามไดเรกทอรี /home/screw/junk จากผลลัพธ์:
find /home/screw -path /home/screw/junk -prune -o -print
ค้นหาไฟล์ตามขนาด
ตัวอย่างนี้ค้นหาไฟล์ทั้งหมดขนาดน้อยกว่า 500 Kilobytes:
find /home/screw -type f -size -500k
ตัวนี้หาไฟล์ระหว่าง 100 และ 200 Kilobytes โดยส่งเงื่อนไข size 2 อัน:
find /home/screw -type f -size +100k -size -200k
หน่วยที่ใช้ได้สำหรับค้นหาตามขนาด:
| b | 512-byte blocks (default หากไม่มี suffix) |
| c | Bytes |
| w | Two-byte words |
| k | Kibibytes (KiB, หน่วย 1024 bytes) |
| M | Mebibytes (MiB, 1024*1024 = 1048576 bytes) |
| G | Gibibytes (GiB, 1024*1024*1024 = 1073741824 bytes) |
วันที่แก้ไขหรือเข้าถึง (Modification or Access Date)
ตัวอย่างต่อไปหาไฟล์ .txt ทั้งหมดที่แก้ไขใน 14 วันที่ผ่านมา:
find /home/screw -name '*.txt' -mtime 14
เพื่อค้นหาตาม last access แทน modification date ใช้ -atime แทน -mtime
คุณยังเพิ่มเครื่องหมาย (+ หรือ –) เพื่อค้นหาไฟล์ที่แก้ไขมากกว่าหรือน้อยกว่าช่วงเวลาที่กำหนด – ตัวอย่างนี้คืนไฟล์ที่แก้ไขมากกว่า 14 วันก่อน:
find /home/screw -name '*.txt' -mtime +14
เพื่อใช้ minutes แทน days เป็นหน่วยเวลา ให้แทน -mmin -amin แทน -mtime และ -atime
เหมือนเดิม มีตัวเลือกเยอะมากให้ผสมผสาน ทั้งหมดอยู่ใน manual รัน:
man find
เจ้าของ User/Group
เพื่อหาไฟล์ทั้งหมดที่เป็นของ root ในไดเรกทอรี /home/screw ให้รัน:
find /home/screw -user root
สิทธิ์ (Permissions)
คำสั่งต่อไปจะหาไฟล์ทั้งหมดที่มี global read/write permissions:
find /home/screw -perm 777
ดูบทความของเราเกี่ยวกับคำสั่ง chmod และมันทำอะไร
การรวมเงื่อนไข (Combination)
การรวมเงื่อนไขค้นหาใดๆ ก็ได้ หากไม่มี operator ระหว่างพวกมัน จะถือว่าทั้งสองเงื่อนไขต้องตรง (คือ AND operator เป็น default)
ตัวอย่างนี้ค้นหา text files ทั้งหมดที่สร้างใน 14 วันที่ผ่านมา ขนาดน้อยกว่า 500kb:
find /home/screw -name '*.txt' -mtime 14 -type f -size -500k
การกระทำกับไฟล์ที่พบ
โดยค่าเริ่มต้น find จะพิมพ์ผลลัพธ์ (เหมือนเรียก action -print)
find /home/screw -name myfile -print
ปรับแต่งรูปแบบผลลัพธ์
คุณสามารถปรับแต่ง output ของผลลัพธ์ให้รวมข้อมูลเพิ่มเติมของไฟล์ที่พบได้ ตัวอย่างนี้พิมพ์ชื่อไฟล์ ตามด้วย dash ตามด้วยขนาดไฟล์ใน bytes:
find /home/screw -name '*.txt' -printf '%f - %s bytes'
มีตัวแปรเยอะมากสำหรับปรับแต่ง output จากขนาดไฟล์ไปจนถึง date fields แยกส่วนสำหรับ modification และ access times – ดู manual สำหรับรายการเต็ม
เขียนผลลัพธ์ลงไฟล์
Redirect ผลลัพธ์ของ find operation ไปไฟล์ข้อความ:
find /home/screw -name myfile > find_results.txt
ลบไฟล์
Action -delete จะลบไฟล์ที่ตรงกัน (ไม่มีการยืนยัน จึงต้องระวัง!):
find /home/screw -name '*.junk' -delete
Execute คำสั่งด้วย -exec / -execdir
คุณสามารถ execute shell command ใดๆ กับแต่ละ find result โดยใช้ action -exec:
find /home/screw -name '*.txt' -exec ls -la {} ';'
-exec จะ execute คำสั่งจาก current working directory หากต้องการ execute จากตำแหน่งของไฟล์ที่พบ ใช้ -execdir แทน:
find /home/screw -name '*.txt' -execdir ls -la {} ';'
ในสองตัวอย่างข้างต้น ls -la รันกับแต่ละ result วงเล็บปีกกา {} จะถูกแทนที่ด้วยผลลัพธ์ของ find และ ‘;’ จบอาร์กิวเมนต์คำสั่งสำหรับ ls เพื่อให้ find รู้ว่าจบที่ไหน
Prompt ยืนยันด้วย -ok / -okdir
Action -ok ทำงานเหมือน -exec แต่ถามก่อนรันคำสั่งที่กำหนด มีประโยชน์หากต้องการลบไฟล์แต่ต้องการถามก่อนลบแต่ละไฟล์:
find /home/screw -name '*.txt' -ok rm {} ';'
-okdir ก็ถามเหมือนกันแต่ execute จากตำแหน่งของไฟล์ที่พบ:
find /home/screw -name '*.txt' -okdir rm {} ';'