จะค้นหาไฟล์ตามประเภทไฟล์ได้อย่างไร?


9

ฉันรู้ว่าฉันสามารถค้นหาไฟล์โดยใช้find: find . -type f -name 'sunrise'. ตัวอย่างผลลัพธ์:

./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise

file sunriseฉันยังรู้ว่าฉันสามารถตรวจสอบประเภทของไฟล์ของไฟล์: ตัวอย่างผลลัพธ์:

sunrise: PEM RSA private key

แต่ฉันจะค้นหาไฟล์ตามประเภทไฟล์ได้อย่างไร

ตัวอย่างเช่นmy-find . -type f -name 'sunrise' -filetype=bash-script:

./astronomy/sunrise
./schedule/sunrise

1
ไม่มี--filetypeตัวเลือกสำหรับคำสั่ง find หรือสิ่งอื่นใดที่จะบอกคุณถึงประเภทของไฟล์ สิ่งเดียวที่คุณสามารถทำได้คือใช้--exec file {} \;แล้วก็สอดเข้าไปgrep Bourneหากคุณกำลังมองหาสคริปต์ทุบตีหรือgrep Perlหากคุณกำลังมองหาสคริปต์ Perl หรือบางอย่างตามสายเหล่านั้น
Nasir Riley

คำตอบ:


13

"ประเภทไฟล์" บนระบบ Unixเป็นสิ่งต่าง ๆ เช่นไฟล์ปกติไดเร็กตอรี่เนมที่มีชื่อไฟล์พิเศษของตัวละครลิงค์สัญลักษณ์ ฯลฯ ซึ่งเป็นประเภทของไฟล์ที่findสามารถกรองได้ด้วย-typeตัวเลือก

findยูทิลิตี้ไม่สามารถแยกแยะความแตกต่างด้วยตัวเองระหว่าง "เชลล์สคริปต์", "ไฟล์ภาพ JPEG" หรืออื่น ๆชนิดของไฟล์ปกติ อย่างไรก็ตามข้อมูลประเภทนี้อาจมีความแตกต่างจากfileยูทิลิตี้ซึ่งจะมีลักษณะเฉพาะในไฟล์เพื่อกำหนดประเภทของไฟล์

วิธีทั่วไปในการทำเลเบลไฟล์ข้อมูลชนิดต่าง ๆ คือประเภท MIMEและfileสามารถกำหนดประเภทไฟล์ MIME ได้


การใช้fileกับfindเพื่อตรวจจับชนิดไฟล์ MIME ปกติและใช้เพื่อค้นหาเชลล์สคริปต์เท่านั้น:

find . -type f -exec sh -c '
    case $( file -bi "$1" ) in
        */x-shellscript*) exit 0
    esac
    exit 1' sh {} ';' -print

หรือใช้bash,

find . -type f \
    -exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';' \
    -print

เพิ่ม-name sunriseก่อน-execหากคุณต้องการตรวจจับสคริปต์ด้วยชื่อนั้นเท่านั้น

findคำสั่งดังกล่าวจะพบไฟล์ปกติทั้งหมดในหรือด้านล่างของไดเรกทอรีปัจจุบันและสำหรับการโทรแต่ละไฟล์เช่นเชลล์สคริปต์สั้นในบรรทัด สคริปต์นี้จะทำงานบนไฟล์พบและออกที่มีสถานะออกศูนย์ถ้าผลลัพธ์ของคำสั่งที่มีสตริงfile -bi /x-shellscriptหากเอาต์พุตไม่มีสตริงนั้นจะออกด้วยสถานะการออกที่ไม่เป็นศูนย์ซึ่งทำให้findไฟล์ต่อไปทันทีโดยทันที หากพบว่าไฟล์เป็นเชลล์สคริปต์findคำสั่งจะดำเนินการส่งออกชื่อพา ธ ของไฟล์ ( -printที่ส่วนท้ายซึ่งอาจถูกแทนที่ด้วยการกระทำอื่น ๆ )

file -biคำสั่งออกจะชนิดไมม์ของไฟล์ สำหรับเชลล์สคริปต์บน Linux (และระบบอื่น ๆ ส่วนใหญ่) สิ่งนี้จะเป็นอย่างไร

text/x-shellscript; charset=us-ascii

ในขณะที่ระบบที่มีfileยูทิลิตี้รุ่นเก่ากว่าเล็กน้อยอาจเป็นได้

application/x-shellscript

บิตทั่วไปคือ/x-shellscriptสตริงย่อย

โปรดทราบว่าใน macOS คุณจะต้องใช้file -bIแทนfile -biเพราะเหตุผล ( -iตัวเลือกทำสิ่งที่แตกต่างกันมาก) เอาต์พุตบน macOS คล้ายกับของระบบ Linux


คุณต้องการที่จะดำเนินการกระทำที่กำหนดเองบางส่วนในแต่ละสคริปต์เชลล์พบคุณสามารถทำอย่างนั้นกับคนอื่น-execในสถานที่ของ-printในfindคำสั่งดังกล่าว แต่มันจะยังเป็นไปได้ที่จะทำ

find . -type f -exec sh -c '
    for pathname do
        case $( file -bi "$pathname" ) in
            */x-shellscript*) ;;
            *) continue
        esac

        # some code here that acts on "$pathname"

    done' sh {} +

หรือมีbash,

find . -type f -exec bash -c '
    for pathname do
        [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue

        # some code here that acts on "$pathname"

    done' bash {} +

ที่เกี่ยวข้อง:


1

คุณสามารถเอ็กซีคิ้วท์findทุกไฟล์ที่พบจากนั้น grep สำหรับผลลัพธ์ที่คุณสนใจ

# When looking for ASCII Text
find . -type -exec file {} \; | grep "ASCII"
# or for MS Word Documents
find . -type f -exec file {} \; | grep "Microsoft Word"

ฉันขอแนะนำให้ทำให้รูปแบบการค้นหาใกล้เคียงกับความคาดหวังของคุณมากที่สุดเพื่อให้จำนวนการจับคู่เป็นบวกผิดพลาดต่ำ

ระวังว่าไฟล์ที่มีบรรทัดใหม่ในชื่อไฟล์อาจทำให้เกิดปัญหากับวิธีการนี้


0

ใช้perl's File::LibMagicโมดูล:

perl -MFile::LibMagic=:easy -MFile::Find -le '
  find sub {
    print $File::Find::name if
      $_ eq "sunrise" and
      -f and
      MagicFile$_ eq "PEM RSA private key"
  }, @ARGV' -- .
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.