แสดงรายการไฟล์ zip ที่มีจำนวนไฟล์น้อยกว่าที่กำหนด


10

ฉันมี.zipไฟล์หลายพันไฟล์ในโฟลเดอร์เดียว ฉันต้องการค้นหาไฟล์ zip ที่มีน้อยกว่า 15 ไฟล์ในนั้น

ฉันรู้ว่าunzip -lสามารถแสดงรายการเนื้อหาของไฟล์ zip แต่ไม่รู้วิธีสร้างเอาต์พุตของไฟล์ zip ที่มีไฟล์น้อยกว่า 15 ไฟล์

คำตอบ:


14
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อ้างอิงด้วย$z
  • if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 ))ทำการ unzip นับไฟล์, แยกจำนวนออกจากผลลัพธ์ (มีวิธีที่ดีกว่าในการแยกเฉพาะตัวเลข แต่ฉันรู้ว่าsedฉันใช้มัน - ดูความคิดเห็นของ @ muruสำหรับวิธีที่ง่ายกว่าที่อาจเร็วกว่าไฟล์จำนวนมาก) และทดสอบว่ามันน้อยกว่า 15 หรือไม่และถ้าเป็น
  • echo "$z" จากนั้นพิมพ์ชื่อไฟล์
  • | tee small-zip-list พิมพ์เอาต์พุตไปยังไฟล์ใหม่เช่นเดียวกับในเทอร์มินัล

ขอบคุณ @Zanna ฉันพยายามเรียกใช้สคริปต์ไฟและมันจะแสดงชื่อไฟล์. zip ทั้งหมดในโฟลเดอร์เสมอแม้ว่าฉันจะลดขนาดตัวเลข 15 ให้เล็กลง แต่ก็แสดงไฟล์. zip ทั้งหมดในโฟลเดอร์
yarone

@yarone ขอโทษฉันพลาดช่องว่าง! ฉันได้แก้ไขแล้วตอนนี้ฉันหวังว่าโปรดลองอีกครั้ง
Zanna

6
อาจใช้งานง่ายขึ้นเล็กน้อยzipinfo: zipinfo -1 foo.zip | wc -lหรือzipinfo -t foo.zip | awk '{print $1}'
muru

@yarone ยินดีต้อนรับมากที่สุด! : D
Zanna

+1 ใช้หนึ่งในสิ่งต่อไปนี้: awk, sed, grep;)
Nonny Moose

9

ตัวเลือกหลามปลายใช้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)

วิธีใช้

  1. คัดลอกสคริปต์ลงในไฟล์เปล่าบันทึกเป็น get_zips.py
  2. เรียกใช้ด้วยไดเรกทอรีและจำนวนไฟล์ (ขั้นต่ำ) ที่ต้องการภายใน:

    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ถ้าจำนวนของรายการที่ระบุไว้มีขนาดเล็กแล้ว


1
งูใหญ่? zipfile !
muru

@muru ขอบคุณอีกครั้งที่ทำให้แตกต่างกัน :)
จาค็อบ Vlijm

9

ใช้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 ก็จะพิมพ์ชื่อไฟล์


5

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

0
for z in *.zip; do if (( $(unzip -Z1 "$z" | wc -l) < 15 )); then echo "$z"; fi;done

การเปลี่ยนแปลงเล็กน้อยเป็นรหัสของ @ zanna "$ (unzip -Z1" $ z "| wc -l)"
user1048382

0

รับจำนวนไฟล์ทั้งหมดโดยใช้ zipinfo:

$ for f in *.zip; do \
  a=($(zipinfo -t "$f")); \
  (($a > 15)) && echo $f; done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.