ฉันจะบังคับให้ unzip / zip ไม่สามารถสร้างไดเรกทอรีย่อยได้อย่างไรเมื่อฉันแตกไฟล์


19

ขึ้นอยู่กับวิธีสร้างไฟล์ zip บางครั้งมันจะแยกไฟล์ทั้งหมดโดยตรงและบางครั้งมันจะแตกไฟล์ลงในไดเรกทอรีย่อย

หากหลังเป็นจริงฉันจะบังคับให้unzipคำสั่ง "ละเว้น" ไดเรกทอรีระดับแรกนั้นได้อย่างไร

ตัวอย่าง:

cd /tmp
wget http://omeka.org/files/omeka-1.5.1.zip
mkdir omeka
unzip omeka-1.5.1.zip -d omeka/
cd omeka/
ll

สิ่งที่ฉันได้รับคือ/tmp/omeka/omeka-1.5.1/:

total 12
drwxr-xr-x 3 root root 4096 2012-05-08 18:44 ./
drwxrwxrwt 6 root root 4096 2012-05-08 18:44 ../
drwxr-xr-x 5 root root 4096 2012-04-20 14:54 omeka-1.5.1/

สิ่งที่ฉันต้องการคือไฟล์ที่แยกไป/tmp/omeka/(หนึ่งระดับขึ้นไปและไม่มีหมายเลขรุ่นรวมอยู่ในโครงสร้างไดเรกทอรี)

/tmp/omeka/(files)

ฉันรู้ว่าฉันสามารถใช้-jตัวเลือกเพื่อ "เส้นทางขยะ" แต่ฉันต้องการเก็บโครงสร้างไดเรกทอรีย่อยไม่ใช่โครงสร้างไดเรกทอรีระดับบนสุด ฉันจะทำสิ่งนี้ได้อย่างไร


ป.ล. : ฉันรู้ว่าฉันสามารถแยกแล้วmvไฟล์ แต่ฉันต้องการที่จะดูว่ามีวิธีที่จะทำตรงนี้ออกมาจากคำสั่ง unzip
4252

ฉันไม่รู้จักเลย แต่ถ้าชื่อไฟล์ตรงกันเสมอ (นอกเหนือจากนามสกุล) ชื่อไดเรกทอรีมันค่อนข้างตรงไปตรงมาที่จะเปลี่ยนชื่อสคริปต์ของ dir ที่แยกออกมา
จ้า

3
ฉันเห็นสิ่งที่คุณพยายามจะทำ แต่ฉันจะไม่แนะนำ การดึงหมายเลขรุ่นจากแหล่งโครงการของคุณเป็นความคิดที่ไม่ดี คุณควรแยกตามปกติและใช้ ln -s หากคุณต้องการชื่อที่สั้นกว่าโดยไม่มีข้อมูลรุ่น วิธีนี้ทำให้คุณรู้ว่าคุณใช้รุ่นใดอยู่เสมอและสามารถอัปเดตเป็นเวอร์ชันใหม่ได้อย่างง่ายดายโดยสลับลิงค์
Burton Samograd

@BurtonSamograd - จะเหมาะ แต่ฉันก็ยังสงสัยว่าถ้ามีวิธีที่มีประสิทธิภาพในการทำเช่นนี้เพราะซอฟต์แวร์บางตัวใช้ Wordpress เป็นตัวอย่างทำให้ทุกรุ่นอยู่ใน/wordpress/ไดเรกทอรี (ไม่มีหมายเลขเวอร์ชั่น) ในไฟล์ zip มันก็โอเคอยู่unzipแล้วmvแต่การควบคุมมันไม่ได้และต้องทำในสองขั้นตอนทำให้ฉันรู้สึกเครียดเล็กน้อย โชคดีที่ Wordpress มี.tar.gzรสชาติเหมือนกัน :)
38490

ลองcd /tmp/omeka && ln -s -T . omeka-1.5.1
James Youngman

คำตอบ:


4

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

mountavfs
cp -Rp ~/.avfs/tmp/omeka-1.5.1.zip\#/omeka-1.5.1 omeka

เนื่องจากเราสมมติว่ามีไดเรกทอรีระดับเดียวในการเก็บถาวรคุณสามารถย่อให้สั้นลงได้

cp -Rp ~/.avfs/tmp/omeka-1.5.1.zip\#/* omeka

@Giles คุณเป็นผู้เชี่ยวชาญที่มาและตอบคำถามทั้งหมดที่ไม่มีใครสามารถตอบได้ดังนั้นฉันเดาว่านี่เป็นวิธีเดียวที่จะทำสิ่งนี้ได้อย่างแท้จริง ฉันหวังว่าจะunzipมีเวทมนตร์ที่จะทำเช่นนี้เช่นการระบุไฟล์ที่จะแตกเช่น*/*ฉันสามารถใช้โดยไม่ต้องติดตั้งยูทิลิตี้อื่น แต่ฉันเดาไม่ได้ ขอบคุณ +1
cwd

6

หากไฟล์ซิปของคุณไม่มีโครงสร้างไดเรกทอรีหรือคุณไม่จำเป็นต้องเก็บรักษาไว้คุณสามารถใช้สิ่งนี้:

cd /tmp
wget http://omeka.org/files/omeka-1.5.1.zip
unzip -j omeka-1.5.1.zip -d omeka
cd omeka
ll

3

สคริปต์นี้ไม่แข็งแกร่ง แต่ทำงานได้ในกรณีง่าย ๆ :

...
dest=omeka
unzip omeka-1.5.1.zip -d $dest/

if [ `ls $dest | wc -l` == 1 ]; then
  subdir=`ls $dest`
  mv $dest/$subdir/* $dest/
  rmdir $dest/$subdir
fi

มันแค่ตรวจสอบเพื่อดูว่ามีไดเรกทอรีย่อยเดียวหรือไม่และถ้าใช่ให้ย้ายทุกอย่างออกไปจากนั้นลบทิ้ง


2

ฉันเพิ่งลงทะเบียนในวันนี้ดังนั้นฉันไม่สามารถโหวต @SteveBennet ได้คำตอบและไม่สามารถเพิ่มความคิดเห็นได้

จากคำตอบของเขาฉันได้สร้างฟังก์ชั่นวนซ้ำดังนี้:

...

shopt -s dotglob # To include hidden files in the move command

function moveSub {
  local dest=$1
  if [ `ls $dest | wc -l` == 1 ]; then
    local subdir=`ls $dest`
    moveSub "$dest/$subdir"
    mv $dest/$subdir/* $dest/
    rmdir $dest/$subdir
  fi
}

moveSub "$dest"

เช่นเดียวกับ @SteveBennet กล่าวว่า: สคริปต์นี้ไม่แข็งแกร่ง แต่ทำงานได้ในกรณีง่าย ๆ

หวังว่ามันจะมีประโยชน์


1

ต้องการpatch --strip=nตัวเลือกที่ดูเหมือนว่า

มันจะเป็นที่พึงปรารถนาที่จะมีตัวเลือกเช่นpatch --strip=number(หรือ-pnumber) ที่สับnumberส่วนประกอบพา ธ ที่จุดเริ่มต้น (อ้างอิงการเปรียบเทียบและการรวมไฟล์: ไดเรกทอรีที่แก้ไข )

โซลูชันอื่นการบังคับใช้

ความล้มเหลวนั้นมีวิธีแก้ไขอีกวิธีหนึ่งคือการแฮ็ก แต่ใช้งานได้ ในกรณีของฉันฉันต้องการเขียนทับไดเรกทอรีที่เต็มไปด้วยไฟล์ที่มีอยู่ด้วยเนื้อหาของ zip โดยไม่ต้องแตก zip เต็มก่อน

เมื่อโซลูชันนี้ใช้งานได้และโซลูชันของ @ Gilles พร้อมใช้งานโซลูชันหลังนี้ก็ใช้ได้เช่นกัน วิธีนี้ไม่ต้องการความพร้อมใช้งานของระบบไฟล์ FUSE

ทำอย่างไร

สมมติว่าคุณรู้ไดเรกทอรีพิเศษในกรณีที่omeka-1.5.1คุณสามารถทำได้:

mkdir omeka
ln -s . omeka/omeka-1.5.1 # create a symlink that redirects output
unzip omeka-1.5.1.zip -d omeka/
rm omeka/omeka-1.5.1 # remote symlink

unzipจะพยายามเปิดเครื่องรูดomeka-1.5.1ซึ่งจริงๆแล้วเป็น symlink ไปที่มี dir เป็นผลให้ไฟล์จะลงจอดomekaโดยตรง

ตัวแปรที่เป็นไปได้

คุณสามารถจินตนาการถึงตัวแปรต่างๆในการเปลี่ยนเส้นทางหนึ่งหรือหลายส่วนของลำดับชั้นแบบแยก

ln -s ../myfoo omeka/omeka-1.5.1/foo
ln -s ../../mybarxyzzy omeka/omeka-1.5.1/subdir/bar

ข้อสรุป

วิธีการแก้ปัญหานี้ค่อนข้างเฉพาะเจาะจง แต่ก็มีกรณีการใช้งานและฉันเพิ่งจะใช้มัน


ทางออกที่ดีถ้าคุณรู้เส้นทาง!
grepsedawk

unzip -lเส้นทางที่สามารถตรวจสอบโดยรายชื่อเนื้อหาซิปแรกเช่นกับ สิ่งนี้อาจเป็นไปโดยอัตโนมัติโดยใช้สคริปต์ที่เป็นส่วนหนึ่งของเส้นทางที่พบได้ทั่วไป
Stéphane Gourichon

โอ้ทั้งหมดมันง่ายกว่าถ้าคุณรู้เส้นทาง ฉันเล่นกับ unzip -l นิดหน่อย แต่มันก็ค่อนข้าง grep / sed / awk มากกว่าที่ฉันตั้งใจไว้
grepsedawk

zipinfo -1อาจเป็นการเริ่มต้นที่ดี กรณีการใช้งานของคุณคืออะไร?
Stéphane Gourichon

github.com/grepsedawk/wow-config/blob/ …ในกรณีนี้ฉันรู้ไดเรกทอรี :)
grepsedawk

1

มีโอกาสมากที่คุณต้องการเรียกใช้งานunzipด้วย-jตัวเลือกดังเช่น:

unzip -j files.zip -d ./output/

แต่คุณอาจประหลาดใจกับพฤติกรรม:

เส้นทางขยะ โครงสร้างไดเรกทอรีของไฟล์เก็บถาวรไม่ได้ถูกสร้างขึ้นใหม่ ไฟล์ทั้งหมดจะถูกฝากไว้ในไดเรกทอรีการแยก (โดยค่าเริ่มต้นไฟล์ปัจจุบัน)

หากคุณแยกfiles.zipในไดเรกทอรีออก./outputและคุณได้รับสิ่งนี้เป็นผล:

./output/files/subfolder1/f1
./output/files/subfolder1/f2

จากนั้น-jตัวเลือกจะให้สิ่งนี้แก่คุณ (เส้นทางทั้งหมดมีลาย):

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