ฉันมีไฟล์เก็บถาวร zip จำนวนมากซึ่งแต่ละไฟล์มีไฟล์เก็บถาวร zip จำนวนหนึ่ง วิธีที่ดีที่สุดในการแยกไฟล์ทั้งหมดที่มีอยู่ในไฟล์ zip นี้และไฟล์เก็บถาวรของไฟล์ย่อยคือ recursively คืออะไร?
ฉันมีไฟล์เก็บถาวร zip จำนวนมากซึ่งแต่ละไฟล์มีไฟล์เก็บถาวร zip จำนวนหนึ่ง วิธีที่ดีที่สุดในการแยกไฟล์ทั้งหมดที่มีอยู่ในไฟล์ zip นี้และไฟล์เก็บถาวรของไฟล์ย่อยคือ recursively คืออะไร?
คำตอบ:
สิ่งนี้จะแยกไฟล์ zip ทั้งหมดลงในไดเรกทอรีปัจจุบันยกเว้นไฟล์ zip ที่อยู่ในนั้น
find . -type f -name '*.zip' -exec unzip -- '{}' -x '*.zip' \;
แม้ว่าสิ่งนี้จะแยกเนื้อหาไปยังไดเรกทอรีปัจจุบัน แต่ไฟล์บางไฟล์อาจไม่ได้อยู่ในไดเรกทอรีนี้อย่างเคร่งครัดเนื่องจากเนื้อหาอาจมีไดเรกทอรีย่อย
หากคุณต้องการไฟล์ทั้งหมดอย่างเคร่งครัดในไดเรกทอรีปัจจุบันคุณสามารถเรียกใช้
find . -type f -mindepth 2 -exec mv -- '{}' . \;
หมายเหตุ: ไฟล์นี้จะอุดตันหากมีสองไฟล์ที่มีชื่อเหมือนกันในไดเร็กทอรีที่ต่างกัน
หากคุณต้องการแตกไฟล์ zip และซิปภายในซ้ำทั้งหมดไฟล์ zip ต่อไปนี้จะแยกไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันและซิปทั้งหมดที่อยู่ในไฟล์นั้นไปยังไดเรกทอรีปัจจุบัน
while [ "`find . -type f -name '*.zip' | wc -l`" -gt 0 ]
do
find . -type f -name "*.zip" -exec unzip -- '{}' \; -exec rm -- '{}' \;
done
while [ "
หา -type f -name '*.? ar' | wc -l" -gt 0 ]; do find -type f -name "*.?ar" -exec mkdir -p '{}.dir' \; -exec unzip -d '{}.dir' -- '../{}' \; -exec rm -- '{}' \;; done
เท่าที่ฉันเข้าใจคุณมีไฟล์เก็บถาวร zip ที่ตัวเองมีไฟล์เก็บถาวร zip และคุณต้องการคลายซิปรหัสไปรษณีย์ที่ซ้อนกันทุกครั้งที่มีการแตกไฟล์
นี่คือสคริปต์ทุบตี 4 ที่คลายซิปรหัสไปรษณีย์ทั้งหมดในไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยซ้ำลบไฟล์ zip แต่ละไฟล์หลังจากคลายซิปแล้วและจะดำเนินต่อไปตราบใดที่ยังมีไฟล์ซิปอยู่ ไฟล์ซิปในไดเรกทอรีย่อยจะถูกดึงข้อมูลสัมพันธ์กับไดเรกทอรีย่อยนั้น คำเตือน: ยังไม่ทดลองทำให้การสำรองข้อมูลของไฟล์ต้นฉบับก่อนที่จะพยายามออกหรือเปลี่ยนrm
โดยการย้ายไฟล์ซิปนอกต้นไม้ไดเรกทอรี
shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ] do
for z; do
( cd -- "$(dirname "$z")" &&
z=${z##*/} &&
unzip -- "$z" &&
rm -- "$z"
)
done
done
สคริปต์ยังจะทำงานใน zsh ถ้าคุณเปลี่ยนสอดคล้องกับshopt
setopt nullglob
นี่คือการพกพาที่เทียบเท่า เงื่อนไขการเลิกจ้างมีความซับซ้อนเล็กน้อยเนื่องจากfind
ไม่ส่งคืนสถานะโดยธรรมชาติเพื่อระบุว่าพบไฟล์ใด ๆ หรือไม่ คำเตือน: ดังกล่าวข้างต้น
while [ -n "$(find . -type f -name '*.zip' -exec sh -c '
cd "${z%/*}" &&
z=${z##*/} &&
unzip -- "$z" 1>&2 &&
rm -- "$z" &&
echo 1
')" ]; do :; done
unzip
ไม่ได้ทำเช่นนี้เพราะวิธี UNIX คือการทำสิ่งหนึ่งและทำได้ดีไม่จัดการกับกรณีพิเศษที่บ้าคลั่งในเครื่องมือทุกอย่าง ดังนั้นคุณต้องใช้เชลล์ (ซึ่งจะทำหน้าที่ของ "การผูกสิ่งต่าง ๆ เข้าด้วยกัน" ได้ดี) สิ่งนี้ทำให้เป็นคำถามการเขียนโปรแกรมและเนื่องจากคำถามการเขียนโปรแกรมที่เป็นไปได้ทั้งหมดได้รับการตอบกลับใน StackOverflow ที่นี่: คุณจะคลายการบีบอัดไฟล์เก็บถาวรในไดเรกทอรีและไดเรกทอรีย่อยจากบรรทัดคำสั่ง Unix ได้อย่างไร
สคริปต์ perl นี้จะแตกไฟล์. zip แต่ละไฟล์ลงในไดเรกทอรีย่อยของตัวเอง รันสคริปต์มากกว่าหนึ่งครั้งเพื่อจัดการไฟล์ซิปที่ซ้อนกัน มันไม่ได้ลบไฟล์. zip หลังจากแตกไฟล์ แต่คุณสามารถทำการเปลี่ยนแปลงนั้นได้โดยเพิ่มการโทรยกเลิกการเชื่อมโยง ()
#!/usr/bin/perl -w
# This script unzips all .zip files it finds in the current directory
# and all subdirectories. Contents are extracted into a subdirectory
# named after the zip file (eg. a.zip is extracted into a/).
# Run the script multiple times until all nested zip files are
# extracted. This is public domain software.
use strict;
use Cwd;
sub process_zip {
my $file = shift || die;
(my $dir = $file) =~ s,/[^/]+$,,;
(my $bare_file = $file);
$bare_file =~ s,.*/,,;
my $file_nopath = $bare_file;
$bare_file =~ s,\.zip$,,;
my $old_dir = getcwd();
chdir($dir) or die "Could not chdir from '$old_dir' to '$dir': $!";
if (-d $bare_file) {
chdir($old_dir);
# assume zip already extracted
return;
}
mkdir($bare_file);
chdir($bare_file);
system("unzip '../$file_nopath'");
chdir($old_dir);
}
my $cmd = "find . -name '*.zip'";
open(my $fh, "$cmd |") or die "Error running '$cmd': $!";
while(<$fh>) {
chomp;
process_zip($_);
}
วิธีที่ง่ายที่สุดคือการใช้ atool: http://www.nongnu.org/atool/ มันเป็นสคริปต์ที่ดีมากที่ใช้โปรแกรม zip, unzip, tar, rar ฯลฯ เพื่อแยกไฟล์เก็บถาวรใด ๆ
ใช้atool -x package_name.zip
เพื่อคลายซิปทั้งหมดหรือถ้าคุณต้องการใช้ในไดเรกทอรีที่มีไฟล์ zip หลายอันใช้งานง่ายfor
วนรอบ :
for f in *; do atool -x $f; fi
(คุณจะต้องcd
เข้าไปในไดเรกทอรีที่ต้องการพร้อมไฟล์ zip ก่อนใช้งาน)
atool
พฤติกรรมของที่นี่ไม่แตกต่างอย่างมากจากการเปิดเครื่องรูดฉันพูดได้ว่ามันไม่แตกไฟล์ ZIP ซ้ำ
คุณจะต้องระมัดระวังการคลายซิปไฟล์ zip ภายในไฟล์ zip โดยอัตโนมัติ:
http://research.swtch.com/2010/03/zip-files-all-way-down.html
เป็นไปได้ที่จะรวมไฟล์ zip ที่สร้างไฟล์ zip เป็นเอาท์พุทซึ่งสร้างไฟล์ zip เป็นเอาท์พุท ฯลฯ ฯลฯ นั่นคือคุณสามารถสร้างไฟล์ zip ที่เป็น oint คงที่ของ "unzip" ของโปรแกรม
นอกจากนี้ฉันดูเหมือนจะจำได้ว่าคนที่ทำไฟล์ซิปที่จะ "ระเบิด" ซึ่งเป็นไฟล์ซิปขนาดเล็กมากจะเปิดเครื่องรูดไปยังเอาต์พุตหลายกิกะไบต์ นี่คือแง่มุมของวิธีการบีบอัด
อาจจะช่วยได้ (ใช้งานได้สำหรับฉัน):
function unzipAll(){
# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`
# while archives exists do extract loop
while [ "$archLstSize" -gt 0 ]; do
# extract and remove all archives (found on single iteration)
for x in $archLst; do
mv "${x}" "${x}_";
unzip "${x}_" -d "${x}" && rm "${x}_";
done; #EO for
# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`
done #EO while
}
ฉันต้องการโซลูชันเช่น Giles 'จากปี 2010 ยกเว้นฉันต้องการรักษาโครงสร้างโฟลเดอร์ไม่ใช่เปิดเครื่องรูดทุกอย่างลงในไดเรกทอรีระดับบนสุด นี่คือสิ่งที่ฉันใช้กับเขาด้วยการเพิ่ม / เปลี่ยนแปลงสามบรรทัด:
#!/bin/bash
shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ]
do
for z
do
( cd -- "$(dirname "$z")" &&
z=${z##*/} &&
cp -- "$z" "$z".bak &&
mkdir -- "$z"dir &&
unzip -- "$z" -d "$z"dir &&
rm -- "$z"
)
done
done
ชำระเงินยูทิลิตี้ที่ใช้ java นี้nzipสำหรับไฟล์ zip ที่ซ้อนกัน การแตกไฟล์และบีบอัดไฟล์ซิปที่ซ้อนกันสามารถทำได้อย่างง่ายดายโดยใช้คำสั่งต่อไปนี้
java -jar nzip.jar -c รายการ -s readme.zip
java -jar nzip.jar -c แยก -s "C: \ project \ readme.zip" -t readme
java -jar nzip.jar -c การบีบอัด -s readme -t "C: \ project \ readme.zip"
PS ฉันเป็นผู้เขียนและยินดีที่จะแก้ไขข้อบกพร่องใด ๆ ได้อย่างรวดเร็ว