tar - แยกโครงสร้างไดเรกทอรีทิ้ง


34

unzipมีตัวเลือกที่ดี-jโดยโครงสร้างไดเรกทอรีของไฟล์เก็บถาวรจะถูกละทิ้งและไฟล์ทั้งหมดจะถูกแยกลงในไดเรกทอรีเดียวกัน

มีวิธีการtarทำงานในลักษณะเดียวกันหรือไม่? ดูเหมือนว่าไม่มีสิ่งใดใน man page ที่สามารถบ่งบอกได้

ดังนั้นจึงมีทางเลือกอื่นที่เด่นกว่าซอฟต์แวร์เสรีซึ่งเป็นเครื่องมือที่จะทำเช่นนั้น?


คำตอบ:


79

GNU tar อาศัยอยู่กับ featuritis ดังนั้นโดยธรรมชาติแล้วยังมีตัวเลือกบางอย่างสำหรับสิ่งนั้น
http://www.gnu.org/software/tar/manual/html_node/transform.html

หากคุณต้องการลบเซ็กเมนต์เส้นทางบางส่วนออก--strip-components=nหรือ--strip=nทำบ่อย ๆ :

 tar xvzf tgz --strip=1

แต่ก็เป็นไปได้ที่จะทำการ regex-rewrite ไฟล์ที่จะแตกไฟล์ (แฟล็กเป็น--transformหรือ--xformและยอมรับ ereg ด้วย/xmodifer):

 tar xvzf tgz --xform='s#^[^/]+#.#x'
                 # or 's#^.+/##x' for discarding all paths

สำหรับรายการ tar คุณต้องมี--show-transformedตัวเลือกเพิ่มเติม:

 tar tvzf tgz --show-transformed --strip=1 --xform='s/abc/xyz/x'

ฉันเชื่อว่าตัวเลือกการเขียนใหม่ยังใช้งานได้กับการบรรจุไม่ใช่สำหรับการแยกเท่านั้น แต่paxมีไวยากรณ์ที่ดีกว่า


4
ทำไมไม่s#.*/##?
l0b0

3
- หยุดทำวันของฉัน ขอบคุณ!
SamStephens

--stripไม่ได้กล่าวถึงในหน้า man os x tar แต่ใช้งานได้แล้วขอบคุณ!
slf

3
ดีกว่าคำตอบที่ยอมรับ
Klaatu von Schlacker

มีความแตกต่างระหว่าง--stripและ--strip-components?
Joel Berkeley

13

คุณสามารถทำได้ง่ายๆในสองขั้นตอน ปรับตามความจำเป็น:

$ mkdir /tmp/dirtree
$ tar xfz /path/to/archive -C /tmp/dirtree
$ find /tmp/dirtree -type f -exec mv -i {} . \;
$ rm -rf /tmp/dirtree

นี่คือวิธีที่ฉันทำ (ใช้find -exec mv -iแทนfind | xargs) .... ขั้นตอนง่าย ๆ ฉันสามารถทำซ้ำในระบบใดก็ได้โดยไม่ต้องพกสคริปต์ไปทำเพื่อฉัน
ต้มตุ๋น Quixote

1
+1 tmpdir=$( mktemp -d )มีประโยชน์เมื่อสร้างไดเรกทอรีชั่วคราว
sorki

8

pax สามารถทำได้:

pax -v -r -s '/.*\///p' < archive.tar

หรือ

zcat archive.tar.gz | pax -v -r -s '/.*\///p'

คุณสามารถตรวจสอบการดำเนินการเปลี่ยนชื่อเป็นอันดับแรกโดยไม่ใช้-rตัวเลือก


1

ทางออกที่เป็นไปได้ที่ไม่ต้องติดตั้งอะไร

  1. ใช้tar tvfเพื่อคว้าไฟล์ทั้งหมดจาก tarball
  2. แตกไฟล์เหล่านั้นทีละไฟล์ - มี tar แตกไปยัง stdout & เปลี่ยนเส้นทางไปที่ $ filename

    tar -tvf $1 | grep -v "^d" | \
                  awk '{for(i=6;i<NF+1;i++) {printf "%s ",$i};print ""}' |\
                  while read filename
                  do
                     tar -O -xf $1 "$filename" > `basename "$filename"`
                  done
    

บันทึกเป็น extract.sh extract.sh myfile.tarและทำงานเป็น มันจะเขียนทับชื่อไฟล์ที่ซ้ำกันที่พบในไดเรกทอรีที่ดึงมาจาก tarball


จริงๆแล้วฉันเพิ่งทดสอบมันบนต้นไม้ dir ที่บ้านและมันล้มเหลวในไฟล์ที่มีช่องว่าง ฉันจะดูว่าฉันไม่สามารถโพสต์อัพเดท
DaveParillo

แก้ไข แต่มันไม่เกือบสวยเท่าเดิม
DaveParillo

-1
tar xf foo.tar.gz foo/path/to/file/bar.mp3 -O > bar.mp3

-Oตัวเลือกสารสกัดจากไฟล์ที่จะออกมาตรฐานและ>การเปลี่ยนเส้นทางว่าการส่งออกลงในไฟล์ ดังนั้นในตัวอย่างของฉันฉันกำลังแยก foo.mp3 และเปลี่ยนเส้นทางไปที่ bar.mp3 ชื่อไฟล์นั้น ๆ

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