**Hidden Content: To see this hidden content your post count must be 1 or greater.**
คำสั่ง find ครับ เครื่องมืออันทรงพลังสำหรับ Unix admin ครับ ไม่ใช่แค่การค้นหาอย่างเดียวครับ ผมได้เพิ่มตัวอย่างที่ใช้กับ Shell Script ของผมเข้าไปด้วยนิดนึง ลองอ่านดูครับ
ค้นหาด้วย Find
find [path ...] [expression]
ง่ายๆ ตรงไปตรงมาคือ find ตามด้วย path เช่น find /home จะหาไฟล์ที่อยู่ใน /home ทั้งหมด คราวนี้ลองใส่เงี่อนไขเข้าไปง่าย เช่น หาไฟล์ที่ลงท้ายด้วย .c เราก็ระบุ option -name เข้าไปเป็น find /home -name "*.c" เป็นต้น
เนื่องจากธรรมชาติของ Unix ซึ่งเขียนด้วยภาษา C จะเป็น case sensitive filename ดังนั้น เราอาจจะเลือกใช้ -iname แทน -name เมื่อไม่สนใจ case ก็ได้ เช่น find /home -name "*.c" จะแสดงทั้ง test.c และ test.C เป็นต้น
นอกจากนี้ยังมี -lname และ -ilname สำหรับกรณีการค้นหา file ที่เป็น symbolic link ด้วย (สำหรับผู้ที่ไม่คุ้นเคย symbolic link คือการสร้าง file ที่ใช้/อ้างอิงไปยังไฟล์อื่น คล้ายกับ short-cut ของ windows)
นอกจากนี้ ยังมีการใส่เงื่อนไขให้ค้นหาตามวันที่ -[acm]time +/-n (n คือจำนวนวัน) เช่น find /home -atime +5 (ในรายละเอียด -atime หมายถึง มีการอ่าน access, -ctime หมายถึงมีการเปลี่ยนสถานะ -mtime หมายถึง มีการแก้ไข) หมายถึงหาไฟล์ที่มีการอ่านมาแล้วเกิน 5 วัน หรือถ้า find /home -atime -5 หายถึงหาไฟล์ที่มีการอ่านภายใน 5 วันที่ผ่านมา เป็นต้น
ซึ่งเราสามารถนำไปประยุกต์ใช้ในการ backup ข้อมูลได้ด้วย กรณีที่ต้องการหาละเอียดเป็นหน่วยนาที ให้เปลี่ยนจาก -atime เป็น -amin เช่น find /home -amin +5 -amin -7 หมายถึงค้นหาไฟล์ที่มีการอ่านระหว่าง 5 ถึง 7 นาทีก่อนเป็นต้น (ในทำนองเดียวกัน -amin หมายถึงมีการอ่าน access, -cmin หมายถึงมีการเปลี่ยนสถานะ, -mmin หมายถึงมีการแก้ไข)
เราอาจจะเปรียบเทียบวันที่กับไฟล์ที่มีอยู่แล้วก็ได้ เช่น find /home -newer /bin/sh จะหาไฟล์ที่ใหม่กว่า /bin/sh เป็นต้น (ในทำนองเดียวกันมี -anewer และ -cnewer เช่นกัน) หรือ find /home -used 5 ใช้ค้นหายไฟล์ที่มีการ access นานเกิน 5 วันจากการเปลี่ยนสถานนะครั้งสุดท้าย
นอกจากนี้เรายังสามารถหาตามขนาด โดยการใช้ -size ช่วยก็ได้ เช่น find /home -size 5k จะหาไฟล์ที่มีขนาด 5 k (โดยประมาณ) หรือใช้ -empty เพื่อหาไฟล์ที่มีขนาดเป็น 0
การหาไฟล์ตาม type เช่น หาเฉพาะ directory ก็ระบุ -type d (ในรายละเอียด type อาจะ เป็น b - block device, c - character device, d - directory, p - named pipe, f - regular file, l - symbolic link, s - socket หรือ D - door ใน Solaris) เป็นต้น นอกจากนี้เรายังใช้ -xtype หรือดูว่าเป็น link ไปยัง type ที่ต้องการก็ได้
การหาไฟล์ตามเจ้าของ หรือ กลุ่มเจ้าของ ใช้ -user uname และ -group gname เช่นเรารู้ว่ามี hacker เข้ามาในระบบในชื่อ nobody เราอาจหาได้ว่า มีไฟล์ได้บ้างที่ nobody สร้างทิ้งไว้ โดยใช้ find / -user nobody เป็นต้น (หรือจะใช้ -uid กับ -gid ซึ่งสามารถหาเป็นช่วงของ user id/ group id ก็ได้)
การหาไฟล์ตาม permission ใช้ -perm mode เช่น find ./ -perm 777 คือหาไฟล์ที่มี permission เป็น 777 เป็นต้น
ค้นหา content ของข้อมูล
หลังจากเรียนรู้เรื่องการใช้ find มาพอควร คราวนี้ลองนำมาผสมกับ xargs และ grep เพื่อใช้หา string ภายในดูบ้าง ปกติแล้ว grep จะให้หา string matching เช่น grep -l printf *.c จะหาทุกไฟล์ใน directory ปัจจุบันที่ลงท้ายด้วย .c และมี printf อยู่ -l เป็นการระบุให้แสดงชื่อไฟล์เท่านั้น (หากต้องการแสดงรายละเอียดของบรรทัดที่มี printf ด้วย ก็ไม่ต้องระบุ -l ก็ได้
คราวนี้ เราจะบอกว่าเราต้องการหาไฟล์ทั้งหมดใน /home ที่ลงท้ายด้วย .c และมีคำว่า printf เราจะนำ find มาผสมกับ grep โดยใช้ xargs เป็นตัวเชื่อม ดังนี้
find ./ -name "*.c" | xargs grep -l printf
xargs จะเอาผลลัพธ์ที่ได้จาก find มาใส่เป็น input ให้กับ command line ของ grep -l printf ดังนั้น เราจะค้นหารายละเอียดได้ในทุกไฟล์ที่ find แสดงผลลัพธ์ออกมา
นอกจากนี้ ยังมี grep -e เพื่อค้นหาเป็น regular express หรือ grep -i เพื่อค้นหาแบบไม่สนใจ case อีกด้วย รายละเอียดเพิ่มเติมสามารถศึกษาได้จาก grep man page (คำสั่ง man grep)
สรุป
สุดท้ายนี้ หวังว่าท่านผู้อ่าน คงจะได้เรียนรู้เรื่องการค้นหาข้อมูลบน unix กันบ้าง ไม่มากก็น้อย
เพิ่มเติม
Find
$ find /mp3-collection -name 'Metallica*' -and -size +10000k
$ find /mp3-collection -size +10000k ! -name "Metallica*"
หาไฟล์ที่ใหญ่กว่า 10 เมก แต่ชื่อไม่ได้นำหน้าด้วย Metallica
$ find /mp3-collection -name 'Metallica*' -or -size +10000k
$ find /mp3collection -name '*.mp3' -size -5000k
ดูว่าไฟล์ไหน น้อยกว่า 5 เมก
$ find / -size +10000k
หาไฟล์ที่ใหญ่เกิน 10 เมก
$ find /home/david -amin -10 -name '*.c'
หาไฟล์ที่มี access time ไม่เกิน 10 นาทีที่ผ่านมา
$ find /home/david -atime -2 -name '*.c'
หาไฟล์ที่มี access time ไม่เกิน 10 ชม. ที่ผ่านมา
$ find /home/david -mmin -10 -name '*.c'
หาไฟล์ที่ถูก modified ไม่เกิน 10 นาทีที่ผ่านมา
$ find /home/david -mtime -2 -name '*.c'
หาไฟล์ที่ถูก modified ไม่เกิน 10 ชม. ที่ผ่านมา
คำสั่ง find นอกจากช่วยค้นหาได้แล้วยังช่วยจัดการกับไฟล์ผลลัพธ์เหล่านั้นได้อีกด้วย
เช่น ต้องการลบไฟล์ที่เก่ากว่า 10 วัน ใน /tmp
find /tmp -type f -mtime +10 -exec rm {} ;
ต้องการหา และดูในไฟล์ว่ามีคำที่ต้องการไหม ถ้ามีก็ลบ
find /var/qmail/queue/mess -type f -exec grep "^Subject: Want a University Diploma" {} ; -print -exec rm {} ;
ลบด้วย จำกัดขนาดด้วย (ไม่เกิน 64k) อันนี้ผมเอาไว้ลบไวรัสที่หลุดเข้ามาในเมล์ของ user
find /home -size -64k -type f -exec grep "document.zip" {} ; -print
ถ้าต้องการลบไฟล์ที่มีอายุเก่าเกิน 7 วัน ใน /backup
find /backup/ -type f -mtime +7 -exec rm -f {} ;
----------------------