ค้นหาไฟล์เก็บถาวรทั้งหมดในรูปแบบไฟล์เก็บถาวรที่หลากหลายและค้นหารูปแบบชื่อไฟล์


11

ที่ดีที่สุดฉันต้องการโทรแบบนี้:

$searchtool /path/to/search/ -contained-file-name "*vacation*jpg"

... เพื่อให้เครื่องมือนี้

  • จะสแกนซ้ำเส้นทางที่กำหนด
  • ใช้ไฟล์ทั้งหมดที่มีรูปแบบไฟล์เก็บถาวรที่สนับสนุนซึ่งอย่างน้อยควรเป็น "ที่พบบ่อยที่สุด" เช่น zip, rar, 7z, tar.bz, tar.gz ...
  • และสแกนรายการไฟล์ของไฟล์เก็บถาวรสำหรับรูปแบบชื่อที่เป็นปัญหา (ที่นี่*vacation*jpg)

ฉันรู้วิธีใช้เครื่องมือค้นหา, tar, unzip และเหมือนกัน ฉันสามารถรวมสิ่งเหล่านี้กับเชลล์สคริปต์ แต่ฉันกำลังมองหาวิธีแก้ปัญหาง่าย ๆ ที่อาจเป็นเชลล์วัน - ไลเนอร์หรือเครื่องมือเฉพาะ (ยินดีแนะนำเครื่องมือ GUI ยินดีต้อนรับ

คำตอบ:


9

(ดัดแปลงมาจากฉันจะ grep ซ้ำผ่านคลังเก็บบีบอัดได้อย่างไร )

ติดตั้งAVFSระบบไฟล์ที่ให้การเข้าถึงแบบโปร่งใสภายในคลังเก็บ ขั้นแรกให้รันคำสั่งนี้หนึ่งครั้งเพื่อตั้งค่ามุมมองของระบบไฟล์ของเครื่องที่คุณสามารถเข้าถึงไฟล์เก็บถาวรเสมือนว่าเป็นไดเร็กทอรี:

mountavfs

หลังจากนี้หาก/path/to/archive.zipเป็นไฟล์เก็บถาวรที่รู้จักแล้ว~/.avfs/path/to/archive.zip#จะเป็นไดเรกทอรีที่มีเนื้อหาของไฟล์เก็บถาวร

find ~/.avfs"$PWD" \( -name '*.7z' -o -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
     -exec sh -c '
                  find "$0#" -name "*vacation*.jpg"
                 ' {} 'Test::Version' \;

คำอธิบาย:

  • เมานต์ระบบไฟล์ AVFS
  • ค้นหาไฟล์เก็บถาวร~/.avfs$PWDซึ่งเป็นมุมมอง AVFS ของไดเรกทอรีปัจจุบัน
  • สำหรับแต่ละไฟล์เก็บถาวรให้ดำเนินการตัวอย่างเชลล์ที่ระบุ (ด้วย$0ชื่อ = ไฟล์เก็บถาวรและ$1รูปแบบ = เพื่อค้นหา)
  • $0#$0เป็นมุมมองของไดเรกทอรีที่เก็บ
  • {\}แทนที่จะ{}ต้องการในกรณีที่การfindแทนที่ภายนอก{}ภายใน-exec ;อาร์กิวเมนต์ (บางคนทำมันบางคนไม่ได้)

หรือใน zsh ≥4.3:

mountavfs
ls -l ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)(e\''
     reply=($REPLY\#/**/*vacation*.jpg(.N))
'\')

คำอธิบาย:

  • ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip) จับคู่ไฟล์เก็บถาวรในมุมมอง AVFS ของไดเร็กทอรีปัจจุบันและไดเร็กทอรีย่อย
  • PATTERN(e\''CODE'\')ใช้รหัสกับการแข่งขันแต่ละแบบ $REPLYชื่อของแฟ้มที่ตรงกับที่อยู่ใน การตั้งค่าreplyอาร์เรย์เปลี่ยนการจับคู่ให้เป็นรายการของชื่อ
  • $REPLY\# คือมุมมองไดเร็กทอรีของไฟล์เก็บถาวร
  • $REPLY\#/**/*vacation*.jpgจับคู่*vacation*.jpgไฟล์ในไฟล์เก็บถาวร
  • ตัวระบุแบบNหมุนทำให้รูปแบบขยายเป็นรายการที่ว่างเปล่าหากไม่มีการจับคู่

9

ถ้าคุณต้องการสิ่งที่เรียบง่ายว่าวิธีการแก้ปัญหา AVFS ผมเขียนสคริปต์ Python ที่จะทำมันเรียกว่าarkfind คุณสามารถทำได้จริงๆ

$ arkfind /path/to/search/ -g "*vacation*jpg"

มันจะทำแบบนี้ซ้ำ ๆ เพื่อให้คุณสามารถดูคลังภายในคลังเก็บของไปจนถึงความลึกโดยพลการ


ขอขอบคุณการบริจาคที่ดี! โดยเฉพาะอย่างยิ่งถ้า AVFS ไม่มีตัวเลือก
mdo

มันจะดีมากถ้ามันรองรับไฟล์ jar
Chemik

@Chemik - สังเกต ! ฉันจะทำงานอีกเล็กน้อยในวันหยุดสุดสัปดาห์นี้ :) JAR ไม่ควรยากเกินไปฉันเชื่อว่ามันเป็นเพียงไฟล์ซิปสู่โลกภายนอก
detly

@Chemik - ฉันลองแล้วและควรรองรับไฟล์ JAR ในรูปแบบปัจจุบันอยู่ดี คุณลองทดสอบดูไหมและถ้ามันไม่ทำงานอย่างที่คุณคาดไว้ให้ยื่นบั๊กที่หน้า Github? (ฉันเพิ่งแก้ไขข้อผิดพลาดดังนั้นโปรดอัปเดตสำเนาของคุณ)
detly

1
ใช่ฉันเห็นแล้วมันใช้งานได้ คุณสามารถเพิ่ม "ไฟล์ JAR" ลงใน README :)
Chemik

2

ทางออกปกติของฉัน:

find -iname '*.zip' -exec unzip -l {} \; 2>/dev/null | grep '\.zip\|DESIRED_FILE_TO_SEARCH'

ตัวอย่าง:

find -iname '*.zip' -exec unzip -l {} \; 2>/dev/null | grep '\.zip\|characterize.txt'

Resuls เป็นเช่น:

foozip1.zip:
foozip2.zip:
foozip3.zip:
    DESIRED_FILE_TO_SEARCH
foozip4.zip:
...

หากคุณต้องการเฉพาะไฟล์ซิปที่มีเพลงฮิต :

find -iname '*.zip' -exec unzip -l {} \; 2>/dev/null | grep '\.zip\|FILENAME' | grep -B1 'FILENAME'

ใช้ชื่อไฟล์ที่นี่สองครั้งดังนั้นคุณจึงสามารถใช้ตัวแปรได้

ด้วยการค้นหาคุณอาจใช้PATH / TO / SEARCH


2

อีกวิธีที่ใช้งานได้คือ zgrep

zgrep -r filename *.zip

1
การดำเนินการของสิ่งzgrepนั้นคืออะไร? ไม่สามารถใช้งานได้กับเครื่องที่ส่งมาพร้อม GNU gzip( /bin/zgrep: -r: option not supported, zgrep (gzip) 1.6)
Stéphane Chazelas

2

ผู้ใช้ที่เป็นมิตรกับ IMHO ควรมีส่วนร่วมในการทุบตีเช่นกัน:

 while read -r zip_file ; do echo "$zip_file" ; unzip -l "$zip_file" | \
 grep -i --color=always -R "$to_srch"; \
 done < <(find . \( -name '*.7z' -o -name '*.zip' \)) | \
 less -R

และสำหรับ tar (อันนี้ยังไม่ทดลอง ... )

 while read -r tar_file ; do echo "$tar_file" ; tar -tf  "$tar_file" | \
 grep -i --color=always -R "$to_srch"; \
 done < <(find . \( -name '*.tar.gz' -o -name '*.tar' \)) | \
 less -R

unzipการใช้งานใดที่สามารถจัดการกับไฟล์ 7z หรือ tar.gz ได้
Stéphane Chazelas

ใช่นั่นเป็นข้อผิดพลาด ... แก้ไข ... เราควรใช้ไบนารีที่ถูกต้องสำหรับประเภทไฟล์ที่ถูกต้อง ... ฉันเพิ่งจะแสดงให้เห็นถึงหนึ่งซับ .. jee อันนี้เกือบจะได้รับพร้อมที่จะ เป็นวิธีการใบเสร็จรับเงิน ...
Yordan Georgiev

0

libarchive's bsdtarสามารถจัดการกับที่สุดของรูปแบบไฟล์เหล่านั้นเพื่อให้คุณสามารถทำ:

find . \( -name '*.zip' -o     \
          -name '*.tar' -o     \
          -name '*.tar.gz' -o  \
          -name '*.tar.bz2' -o \
          -name '*.tar.xz' -o  \
          -name '*.tgz' -o     \
          -name '*.tbz2' -o    \
          -name '*.7z' -o      \
          -name '*.iso' -o     \
          -name '*.cpio' -o    \
          -name '*.a' -o       \
          -name '*.ar' \)      \
       -type f                 \
       -exec bsdtar tf {} '*vacation*jpg' \; 2> /dev/null

ซึ่งคุณสามารถลดความซับซ้อน (และปรับปรุงเพื่อให้ตรงตามตัวพิมพ์ใหญ่ - เล็ก) กับ GNU findด้วย:

find . -regextype egrep \
       -iregex '.*\.(zip|7z|iso|cpio|ar?|tar(|\.[gx]z|\.bz2)|tgz|tbz2)' \
       -type f \
       -exec bsdtar tf {} '*vacation*jpg' \; 2> /dev/null

ไม่พิมพ์เส้นทางของไฟล์เก็บถาวรที่*vacation*jpgพบไฟล์เหล่านั้น หากต้องการพิมพ์ชื่อนั้นคุณสามารถแทนที่บรรทัดสุดท้ายด้วย:

-exec sh -ac '
   for ARCHIVE do
     bsdtar tf "$ARCHIVE" "*vacation*jpg" |
       awk '\''{print ENVIRON["ARCHIVE"] ": " $0}'\''
   done' sh {} + 2> /dev/null

ซึ่งให้ผลลัพธ์เช่น:

./a.zip: foo/blah_vacation.jpg
./a.zip: bar/blih_vacation.jpg
./a.tar.gz: foo/blah_vacation.jpg
./a.tar.gz: bar/blih_vacation.jpg

หรือด้วยzsh:

setopt extendedglob # best in ~/.zshrc
for archive (**/*.(#i)(zip|7z|iso|cpio|a|ar|tar(|.gz|.xz|.bz2)|tgz|tbz2)(.ND)) {
  matches=("${(f@)$(bsdtar tf $archive '*vacation*jpg' 2> /dev/null)"})
  (($#matches)) && printf '%s\n' "$archive: "$^matches
}

โปรดทราบว่ามีหลายรูปแบบไฟล์อื่น ๆ ที่เป็นเพียงzipหรือtgzไฟล์ที่ปลอมตัวเหมือน.jarหรือ.docxไฟล์ คุณสามารถเพิ่มสิ่งเหล่านั้นในfind/ zshรูปแบบการค้นหาของคุณbsdtarไม่สนใจเกี่ยวกับส่วนขยาย (เช่นในมันไม่พึ่งพาส่วนขยายในการกำหนดประเภทของไฟล์)

โปรดทราบว่า*vacation*.jpgด้านบนถูกจับคู่บนพา ธ สมาชิกไฟล์เก็บถาวรแบบเต็มไม่เพียง แต่ชื่อไฟล์ดังนั้นมันจะจับคู่vacation.jpgแต่เปิดvacation/2014/file.jpgด้วย

เพื่อให้ตรงกับชื่อไฟล์เท่านั้นเคล็ดลับอย่างหนึ่งคือการใช้โหมดแยกใช้-s(ทดแทน) ซึ่งใช้ regexps พร้อมกับpตั้งค่าสถานะเพื่อพิมพ์ชื่อของไฟล์ที่ตรงกันแล้วตรวจสอบให้แน่ใจว่าไม่มีการแตกไฟล์เช่น:

bsdtar -'s|.*vacation[^/]*$||' -'s|.*||' -xf "$archive"

โปรดทราบว่ามันจะส่งออกรายการใน stderr และผนวก>>กับทุกบรรทัด ไม่ว่าในกรณีใด ๆbsdtarเช่นtarการใช้งานส่วนใหญ่อาจทำให้ชื่อไฟล์บนจอแสดงผลยุ่งเหยิงหากมีอักขระบางตัวเช่นขึ้นบรรทัดใหม่หรือแบ็กสแลช (แสดงผลเป็น\nหรือ\\)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.