การสร้างไฟล์เก็บถาวรโดยใช้ tar รวมถึง 'dotfiles' ทั้งหมด แต่ไม่รวมไดเรกทอรีย่อยทั้งหมดและ / wo โครงสร้างไดเรกทอรี


18

ฉันต้องการสำรองข้อมูล 'dotfiles' (fe .zshrc) ทั้งหมดภายใต้ไดเรกทอรีบ้านของฉันด้วยtarแต่ไม่รวมโครงสร้างไดเรกทอรีและไดเรกทอรีย่อยทั้งหมด

ฉันได้ลองหลายครั้งด้วยคำสั่งที่แตกต่างกัน แต่สิ่งที่ดีที่สุดที่ฉันทำได้คือการเก็บถาวรซึ่งรวมถึงไดเรกทอรีที่ซ่อนอยู่$HOMEด้วย

#!/bin/zsh
BACKUPFILE=dotfile_backup.tar.gz
tar --create --file=$HOME/$BACKUPFILE --auto-compress --no-recursion --exclude=. --exclude=.. --exclude=*/ --directory=$HOME .*

ฉันคิดเกี่ยวกับการใช้findและการวางท่อผลลัพธ์เพื่อ tar แต่ไม่มีโชค มีใครบางคนรู้วิธีที่จะทำสิ่งนี้ให้สำเร็จซึ่งดูเหมือนจะง่ายหรือไม่?

PS: ส่วนใหญ่เวลาที่ฉันใช้ tar เพื่อสร้างที่เก็บถาวรฉันต้องคิดถึงการ์ตูน xkcd:

xkcd 1168 :)


คำตอบของซิมทำงานได้ แต่ถ้าใครมี regex ที่ตรงกับไฟล์ที่ซ่อนเท่านั้นโปรดโพสต์มัน!
klingt.net

1
แน่นอนว่านี่จะเป็นผลดีกับเชลล์ของคุณ ผมเข้าใจ zsh ที่มี globs ที่เลือกเฉพาะไฟล์ - *(.)- และฉันคิดว่าไม่รวมมัน.และ..จาก.*โดยค่าเริ่มต้น (และพวกเขาจะไม่ได้หยิบขึ้นมา.*(.)แล้วเพราะมันเลือกไฟล์เท่านั้น) ฉันไม่ได้ใช้ zsh ด้วยตัวเองดังนั้นฉันจึงไม่แน่ใจที่จะเปลี่ยนเป็นคำตอบ
evilsoup

คำตอบ:


14

คุณสามารถใช้คำสั่งนี้เพื่อสำรองข้อมูล dotfiles ( .<something>) ทั้งหมดใน$HOMEไดเรกทอรีของคุณ:

$ cd ~
$ find . -maxdepth 1 -type f -name ".*" -exec tar zcvf dotfiles.tar.gz {} +

regex ใช้ tar เพียง?

วิธีที่ # 1

ฉันค้นคว้าข้อมูลนี้มาไม่นานและว่างเปล่า ปัจจัยที่มีข้อ จำกัดtarคือเมื่อมีการดำเนินการมันไม่รวมเครื่องหมายต่อท้ายสแลช ( /) ที่แสดงขึ้นพร้อมกับไดเรกทอรีไม่ได้เป็นส่วนหนึ่งของสมการเมื่อ tar ดำเนินการจับคู่รูปแบบ

นี่คือตัวอย่าง:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*/'} .*
.qalculate/
.qt/
.qterm/
.qtoctave/
.RapidSVN
.RData
.Rhistory

ตัวแปรนี้มีข้อยกเว้นของ.*/และคุณสามารถเห็นได้ด้วยสวิตช์ verbose เปิดเพื่อ tar -vซึ่งไดเรกทอรีเหล่านี้กำลังผ่านการแยกออก

วิธีที่ # 2

ฉันคิดว่าอาจเปลี่ยน--no-wildcards-match-slashหรือ--wildcards-match-slashจะผ่อนคลายความโลภของ.*/แต่ก็ไม่มีผลเช่นกัน

การนำเครื่องหมายทับออกจากการแยก.*ไม่ได้เป็นตัวเลือกอย่างใดอย่างหนึ่งเนื่องจากจะบอกtarให้ยกเว้น dotfiles และ dotdirectories ทั้งหมด:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*'} .*
$

วิธีการ # 3 (น่าเกลียด!)

ดังนั้นทางเลือกเดียวที่อื่น ๆ tarที่ฉันสามารถตั้งครรภ์คือการให้รายชื่อของไฟล์ที่จะ บางสิ่งเช่นนี้

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --wildcards-match-slash --exclude={'.','..','.*/'} $(ls -aF | grep -E "^\..*[^/]$")
.RapidSVN
.RData
.Rhistory

วิธีการนี้มีปัญหาหากจำนวนไฟล์เกินจำนวนสูงสุดของพื้นที่ว่างสำหรับการส่งอาร์กิวเมนต์ไปยังคำสั่งจะเป็นปัญหาหนึ่งที่จ้องมอง อีกอันคือมันน่าเกลียดและซับซ้อนเกินไป

แล้วเราเรียนรู้อะไร

ดูเหมือนจะไม่มีวิธีที่ตรงไปตรงมาและสง่างามที่จะเข้าใจสิ่งนี้โดยใช้tar& การแสดงออกปกติ เพื่อที่จะแสดงความคิดเห็นของ @ terdon เป็นfind ... | tar ...วิธีที่เหมาะสมกว่าในการทำเช่นนี้


ฉันอยากจะทำมันให้เสร็จregexแต่ฉันควรจะรู้ว่ามันจะไม่ทำงานอย่างนั้น :)
klingt.net

@ klingt.net - น่าจะเป็นไปได้ฉันกำลังหาอยู่
slm

@ klingt.net ทำไมคุณถึงชอบวิธีที่ซับซ้อนกว่านี้? การใช้regexคุณอาจจะต้องหลบหนีจุดชั้นนำและจะมีปัญหาไม่สนใจและ. ..ฉันแน่ใจว่าเป็นไปได้เพราะ slm อาจจะแสดงให้เห็น แต่ฉันไม่เห็นว่าทำไมมันจะคุ้มค่า
terdon

1
@ klingt.net - ทุกอย่างที่พบได้รับคำสั่งที่ส่งผ่านเป็นอาร์กิวเมนต์ไปยังfind tarคำสั่ง{}ระบุตำแหน่งที่คุณต้องการให้ผลลัพธ์เหล่านั้นอยู่ใน-execคำสั่งที่เกี่ยวข้อง การแจ้ง+ว่าจะเพิ่มผลลัพธ์จำนวนมากจากfindที่จะพอดีกับบรรทัดคำสั่งและโทรtarเพียงสองสามครั้งมากกว่าทุกครั้งที่พบผลลัพธ์
slm

1
@ klingt.net - ไม่มีทางที่จะใช้สิ่งนี้ได้สำเร็จregexและtarเนื่องจากไม่มีวิธีในการแยกไดเรกทอรี dot ( .blah/) กลาสีเรือไม่ได้ใช้เครื่องหมายสแลชต่อท้ายเมื่อทำการแยกออก
slm

4

การควบคุมไฟล์ที่ตรงกันประเภทนี้เป็นวิธีที่อยู่นอกเขตความสะดวกสบายของน้ำมันดิน กฎสำหรับการจับคู่ไฟล์จะถูก จำกัด เฉพาะการจับคู่ที่ง่ายกว่าชื่อ

find เป็นวิธีหนึ่ง แต่เนื่องจากคุณมี zsh คุณจึงง่ายขึ้น:

tar -cf "$HOME/$BACKUPFILE" --auto-compress .*(.)

ที่.อยู่ในวงเล็บในตอนท้ายของการแสดงออกทางสัญลักษณ์เป็นรอบคัดเลือก globว่า“เพียงตรงกับไฟล์ปกติ”

ลิงก์สัญลักษณ์ไปยังไฟล์ปกติไม่ตรงกัน หากคุณเปลี่ยนเป็นไฟล์.*(-.)เหล่านั้นจะถูกรวมไว้ แต่ไฟล์จะไม่สิ้นสุดลงในไฟล์เก็บถาวรเว้นแต่ไฟล์จะถูกรวมไว้ด้วย หากคุณต้องการแทนที่ลิงก์สัญลักษณ์โดยเป้าหมายให้ทำ.*(-.:A):Aเพิ่มตัวขยายส่วนขยายประวัติที่แก้ไขลิงก์สัญลักษณ์ทั้งหมดไปยังเส้นทางที่ไม่ได้ใช้ลิงก์สัญลักษณ์


3

คำตอบนี้ขึ้นอยู่กับ slm's แต่ฉันจะแสดงวิธีรวมไดเรกทอรีที่ขึ้นต้นด้วย .

วิธี zip ไฟล์ dot ในโฮมไดเร็กตอรี่ของคุณ:

$ cd
$ find . -maxdepth 1 -type f -name ".?*" -exec tar czfv dotfiles.tgz {} +

หากต้องการรวมไดเรกทอรี:

$ find . -maxdepth 1 -name ".?*" -exec tar czfv dotfiles.tgz {} +

?เป็นตัวเลือกในคำสั่งแรก แต่ไม่ได้อยู่ในที่สองมิฉะนั้นfindจะมี.ไดเรกทอรี (ปัจจุบัน)


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