ฉันมี.zipไฟล์หลายพันไฟล์ในโฟลเดอร์เดียว ฉันต้องการค้นหาไฟล์ zip ที่มีน้อยกว่า 15 ไฟล์ในนั้น
ฉันรู้ว่าunzip -lสามารถแสดงรายการเนื้อหาของไฟล์ zip แต่ไม่รู้วิธีสร้างเอาต์พุตของไฟล์ zip ที่มีไฟล์น้อยกว่า 15 ไฟล์
ฉันมี.zipไฟล์หลายพันไฟล์ในโฟลเดอร์เดียว ฉันต้องการค้นหาไฟล์ zip ที่มีน้อยกว่า 15 ไฟล์ในนั้น
ฉันรู้ว่าunzip -lสามารถแสดงรายการเนื้อหาของไฟล์ zip แต่ไม่รู้วิธีสร้างเอาต์พุตของไฟล์ zip ที่มีไฟล์น้อยกว่า 15 ไฟล์
คำตอบ:
for z in *.zip; do if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 )); then echo "$z"; fi; done
สิ่งนี้แสดงรายการ.zipไฟล์ที่มีไฟล์น้อยกว่า 15 ไฟล์เป็น stdout (ในเทอร์มินัล) ดังนั้นหากคุณต้องการสร้างไฟล์รายการคุณสามารถteeออกหรือเปลี่ยนเส้นทาง ที่นี่จะอ่านง่ายขึ้นสร้างไฟล์รายการที่ส่วนท้ายเช่นเดียวกับการพิมพ์ในเครื่อง
for z in *.zip; do
if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 )); then
echo "$z"
fi
done | tee small-zip-list
for z in *.zipวนไฟล์ที่ลงท้ายด้วย.zipและทำบางสิ่งบางอย่างกับแต่ละไฟล์ซึ่งแสดงโดยตัวแปรที่zอ้างอิงด้วย$zif (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 ))ทำการ unzip นับไฟล์, แยกจำนวนออกจากผลลัพธ์ (มีวิธีที่ดีกว่าในการแยกเฉพาะตัวเลข แต่ฉันรู้ว่าsedฉันใช้มัน - ดูความคิดเห็นของ @ muruสำหรับวิธีที่ง่ายกว่าที่อาจเร็วกว่าไฟล์จำนวนมาก) และทดสอบว่ามันน้อยกว่า 15 หรือไม่และถ้าเป็นecho "$z" จากนั้นพิมพ์ชื่อไฟล์| tee small-zip-list พิมพ์เอาต์พุตไปยังไฟล์ใหม่เช่นเดียวกับในเทอร์มินัล zipinfo: zipinfo -1 foo.zip | wc -lหรือzipinfo -t foo.zip | awk '{print $1}'
ตัวเลือกหลามปลายใช้python's zipfile(ตามที่แนะนำโดย @muru ขอบคุณ!)
#!/usr/bin/env python3
import os
import sys
from zipfile import ZipFile
dr = sys.argv[1]
for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:
if len(ZipFile(zp, "r").namelist()) < int(sys.argv[2]):
print(zp)
get_zips.pyเรียกใช้ด้วยไดเรกทอรีและจำนวนไฟล์ (ขั้นต่ำ) ที่ต้องการภายใน:
python3 /path/to/get_zips.py /full/path/to/directory_with_zips 15
สคริปต์:
แสดงรายการ.zipไฟล์ภายในไดเรกทอรี:
for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:ดูข้างในไฟล์และนับจำนวนไฟล์:
if len(ZipFile(file, "r").namelist()) < n:
print(file)
เพียงพิมพ์ไฟล์ (+ เส้นทาง) nถ้าจำนวนของรายการที่ระบุไว้มีขนาดเล็กแล้ว
ใช้awk :
for i in ~/path/to/your/folder/*.zip; do if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 )); then echo "$i"; fi; done
หรือสามารถทำได้ด้วยสคริปต์
สร้างสคริปต์ zip.sh
#!/bin/bash
for i in ~/path/to/your/folder/*.zip; do
if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 )); then
echo "$i"
fi
done
บันทึกไว้ในโฮมโฟลเดอร์ & ทำให้มันสามารถchmod +x zip.shเรียกใช้ด้วยและเรียกใช้จากเทอร์มินัล./zip.sh
ที่นี่if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 )),
unzip -l $i มันจะนับจำนวนไฟล์จากไฟล์ zip ตามลำดับ & จากเอาต์พุต
awk 'END {print $(NF-1)}' grep ที่นับจำนวนเท่านั้นหากน้อยกว่า 15 ก็จะพิมพ์ชื่อไฟล์
Perl Archive::Zipนอกจากนี้ยังมีแพคเกจสำหรับการจัดการข้อมูลที่เก็บซิป สคริปต์ด้านล่างใช้ไฟล์ซิปเป็นอาร์กิวเมนต์บรรทัดคำสั่งและให้เอาต์พุตบรรทัดคำสั่งพร้อมชื่อและจำนวนไฟล์ภายในไฟล์เก็บถาวร
#!/usr/bin/env perl
use strict;
use warnings;
use Archive::Zip;
foreach (@ARGV){
my $fh = Archive::Zip::->new();
if (my $error = $fh->read($_)){
die "Read error:" . $_;
}
if($fh->numberOfMembers() < 15 ){
printf("%s\t%d\n",$_,$fh->numberOfMembers());
}
}
ทดสอบการทำงาน:
$ ./count_zip_contents.pl *.zip
129804-findmac.py.zip 1
Re%3a_China_and_East_Asia_%5bHIS-1250-010_31616.201730%5d%3a_Team_up_for_East_Asian_History_class.zip 4
University_Formal_jpg&tif.zip 5
indicator-places-master.zip 4
lab 5.zip 8
for z in *.zip; do if (( $(unzip -Z1 "$z" | wc -l) < 15 )); then echo "$z"; fi;done
รับจำนวนไฟล์ทั้งหมดโดยใช้ zipinfo:
$ for f in *.zip; do \
a=($(zipinfo -t "$f")); \
(($a > 15)) && echo $f; done