Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม Bash

เชี่ยวชาญคำสั่ง 'find' ใน Linux: ตัวอย่างปฏิบัติจริง & คู่มือไวยากรณ์

คำสั่ง 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 patternpath ของไฟล์ตรงกับ pattern pattern
-readableจับคู่ไฟล์ที่ user ปัจจุบันอ่านได้
-size nไฟล์ใช้พื้นที่ น้อยกว่า มากกว่า หรือเท่ากับ n หน่วย ปัดขึ้น (ดูตารางด้านล่างสำหรับหน่วยที่ใช้ได้)
-type cไฟล์เป็นประเภท c (ดูตารางด้านล่างสำหรับค่า c)
-user nameไฟล์เป็นของ user name
Actions (การกระทำ)
-printแสดงชื่อไฟล์ (default action)
-pruneถ้าไฟล์เป็น directory อย่าลงไปลึกในมัน
-depthประมวลผลเนื้อหาแต่ละ directory ก่อน directory เอง
-deleteลบไฟล์ที่ตรงกัน -delete ยังทำงานเหมือน option (เพราะ imply -depth)
-exec commandexecute command
-execdir commandเหมือน -exec แต่รันคำสั่งจาก subdirectory ที่มีไฟล์ที่ตรงกัน
-ok commandเหมือน -exec แต่ถามผู้ใช้ก่อน
-okdir commandเหมือน -execdir แต่ถามผู้ใช้ก่อนเหมือน -ok
-printf formatพิมพ์รายละเอียดไฟล์ใน format

ตัวดำเนินการในนิพจน์ (Operators in Expressions)

ตัวดำเนินการสามารถใช้เชื่อมรายการในนิพจน์ได้:

-oOR
-aAND (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

ประเภทที่มีอยู่:

bBlock (buffered) special
cCharacter (unbuffered) special
dDirectory
pNamed pipe (FIFO)
fRegular file
lSymbolic link; ไม่เป็นจริงหาก -L หรือ -follow อยู่ในผลกระทบ ยกเว้น link ชำรุด
sSocket

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

หน่วยที่ใช้ได้สำหรับค้นหาตามขนาด:

b512-byte blocks (default หากไม่มี suffix)
cBytes
wTwo-byte words
kKibibytes (KiB, หน่วย 1024 bytes)
MMebibytes (MiB, 1024*1024 = 1048576 bytes)
GGibibytes (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 {} ';'