फ़ाइलें ढूंढें और उन्हें टार करें (रिक्त स्थान के साथ)


110

ठीक है, यहाँ इतनी सरल समस्या है। मैं एक साधारण बैक अप कोड पर काम कर रहा हूं। यह ठीक काम करता है, सिवाय इसके कि फाइलों में जगह हो। इस तरह से मैं फ़ाइलों को ढूंढ रहा हूं और उन्हें टार आर्काइव में जोड़ रहा हूं:

find . -type f | xargs tar -czvf backup.tar.gz 

समस्या तब है जब फ़ाइल के नाम में एक स्थान है क्योंकि टार को लगता है कि यह एक फ़ोल्डर है। मूल रूप से एक तरीका है कि मैं खोज से परिणामों के आसपास उद्धरण जोड़ सकता हूं? या इसे ठीक करने का एक अलग तरीका?


12
उपयोग करने के लिए सबसे अच्छा तरीका है find ... | xargs ...-print0 / -0 से प्रत्येक पर पैरामीटर का उपयोग करने के लिए है: find -print0 ... | xargs -0 ...। यह फ़ाइल नाम को एक अशक्त चरित्र से अलग करेगा, जिसका अर्थ है कि आपके फ़ाइल नाम में रिक्त स्थान या नई लाइनें या अन्य अजीब चीजें हो सकती हैं और यह अभी भी काम करेगा।
porges

8
Xargs और tar का उपयोग करने में एक समस्या है, जब आपके पास बड़ी संख्या में फाइलें हैं, तो xargs बार-बार tar -c को आमंत्रित करेगा, और यह आपके संग्रह को अधिलेखित करता रहेगा, और परिणाम यह है कि आपके पास उन सभी फ़ाइलों की अपेक्षा नहीं होगी जिनकी आप अपेक्षा करते हैं । देखें इस अधिक विस्तृत विवरण और मेरा उत्तर नीचे।
स्टीव केहलेट

जवाबों:


217

इसे इस्तेमाल करो:

find . -type f -print0 | tar -czvf backup.tar.gz --null -T -

यह:

  • रिक्त स्थान, newlines, अग्रणी डैश, और अन्य funniness के साथ फ़ाइलों के साथ सौदा
  • फ़ाइलों की एक असीमित संख्या संभाल
  • बार-बार का उपयोग कर की तरह अपने backup.tar.gz ओवरराइट नहीं करेगी tar -cसाथ xargsक्या करेंगे आप फ़ाइलों की एक बड़ी संख्या है, जब

और देखें:


1
यदि आप कुछ समय पहले सेड के माध्यम से अपनी खोज को पाइप करना चाहते हैं तो आप यह कैसे करेंगे? जैसे खोजो। –प्रति ० | sed / backups / d | टार ....
ब्रैड पार्क्स

8
ध्यान दें कि यदि कई शर्तें हैं, तो आपको कोष्ठक जोड़ने की आवश्यकता है। अन्यथा -print0केवल अंतिम अभिव्यक्ति पर लागू होता है। उदाfind . \( -type f -o -name '*.c' \) -print0 | ...
निमरोडम

1
मज़े के लिए, यहाँ साइबरगन का उपयोग करते हुए इसका एक विंडोज संस्करण है:c:\cygwin\bin\find . -regextype posix-egrep -regex '.*(sln^|vcxproj^|filters)$' -print0 | c:\cygwin\bin\tar -cvf MS_Projects.tar --null -T -
जॉन

1
@ आप टार कमांड के अंत में '-' विकल्प क्या है कृपया बता सकते हैं। मैं इसे GNU टार के मैन पेज में नहीं ढूँढ सकता।
शफू मे

निश्चित बात, यह एक पैरामीटर है -T, और इसका मतलब है कि मानक इनपुट से फ़ाइल नाम पढ़ें: यदि आप `- फाइल्स-से 'के लिए फ़ाइल नाम के रूप में एक एकल डैश देते हैं (यानी, आप या तो निर्दिष्ट करते हैं - फाइल-से = - या -T -), तब फ़ाइल नाम मानक इनपुट से पढ़े जाते हैं
स्टीव केहलेट

14

आप जो चाहते हैं उसे प्राप्त करने का एक और तरीका हो सकता है। मूल रूप से,

  1. का प्रयोग करें खोजने के जो भी फाइल को आप देख रहे हैं करने के लिए उत्पादन पथ के लिए आदेश। अपने चयन के फ़ाइल नाम पर पुनर्निर्देशन को रोकें
  2. फिर -T विकल्प के साथ टार करें जो इसे फ़ाइल स्थानों की सूची लेने की अनुमति देता है (एक जिसे आपने अभी ढूंढा है!)

    find . -name "*.whatever" > yourListOfFiles
    tar -cvf yourfile.tar -T yourListOfFiles
    

यहाँ एक उत्तर दिया गया है कि उन पर नई
कहानियों के साथ फिल्म्स

8

चलाने की कोशिश करें:

    find . -type f | xargs -d "\n" tar -czvf backup.tar.gz 

7

क्यों नहीं:

tar czvf backup.tar.gz *

यकीन है कि यह खोज और फिर xargs का उपयोग करने के लिए चतुर है, लेकिन आप इसे कठिन तरीके से कर रहे हैं।

अपडेट: पोर्जेस ने एक खोज-विकल्प के साथ टिप्पणी की है जो मुझे लगता है कि मेरे जवाब से बेहतर उत्तर है, या अन्य एक: find -print0 ... | xargs -0 ....


मेरा पूरा कोड केवल उन वस्तुओं का बैकअप लेगा जो पिछले दिन संशोधित किए गए हैं। चूँकि इसकी दैनिक बैक अप है, इसलिए मैं फ़ाइल आकार को बचाने के लिए बार-बार जानकारी नहीं चाहता (मेरे पास हर 15 दिनों में एक पूर्ण बैक अप है)।
कालेब केस्टर

इसे एक बेहतर SO प्रश्न बनाने के लिए, मैं "मज़बूती से खोज, xargs और टार का उपयोग करके" के बारे में प्रश्न पूछूंगा। आपका शीर्षक और प्रश्न वास्तव में निर्दिष्ट नहीं करता है कि आपको खोज और एक्सएआरजीएस की आवश्यकता है, और फिर भी आप करते हैं।
वारेन पी

xargs ... tar c ...यदि फ़ाइलों की सूची बहुत लंबी है और दूसरी बार xargsनिष्पादित होगी, तो बनाए गए पहले संग्रह को अधिलेखित कर देगी tar! ओवरराइटिंग से बचने के लिए आप उपयोग कर सकते हैं xargs -xलेकिन तब पुरालेख अधूरा हो सकता है। वैकल्पिक पहले tar c ...और फिर संभवतः बार-बार हो सकता है tar r ...। (विश्वसनीयता में मेरा योगदान :)
pabouk

3

यदि आपके पास कई फाइलें या निर्देशिकाएं हैं और आप उन्हें स्वतंत्र *.gzफाइल में पिन करना चाहते हैं तो आप ऐसा कर सकते हैं। ऐच्छिक-type f -atime

find -name "httpd-log*.txt" -type f -mtime +1 -exec tar -vzcf {}.gz {} \;

यह सेक करेगा

httpd-log01.txt
httpd-log02.txt

सेवा

httpd-log01.txt.gz
httpd-log02.txt.gz



2

@Steve Kehlet पोस्ट में एक टिप्पणी जोड़ देगा लेकिन 50 प्रतिनिधि (RIP) की आवश्यकता है।

किसी ऐसे व्यक्ति के लिए जिसने इस पोस्ट को कई गोग्लिंग के माध्यम से पाया है, मुझे एक विशिष्ट समय सीमा को देखते हुए न केवल विशिष्ट फ़ाइलों को खोजने का एक तरीका मिला, बल्कि रिश्तेदार पथ या व्हाट्सएप को भी शामिल करना होगा जो त्रुटियों को पैदा करेगा। (आपको बहुत अच्छा लगता है।)

find . -name "*.pdf" -type f -mtime 0 -printf "%f\0" | tar -czvf /dir/zip.tar.gz --null -T -
  1. . रिश्तेदार निर्देशिका

  2. -name "*.pdf" pdfs (या किसी फ़ाइल प्रकार) के लिए देखें

  3. -type f फ़ाइल देखने के लिए टाइप करें

  4. -mtime 0 पिछले 24 घंटों में बनाई गई फ़ाइलों को देखें

  5. -printf "%f\0"नियमित -print0या -printf "%f"मेरे लिए काम नहीं किया। मैन पेज से:

यह उद्धरण उसी तरह से किया जाता है जैसे कि GNU ls के लिए। यह एक ही उद्धृत तंत्र नहीं है, जैसे कि -ls और -fl के लिए उपयोग किया जाता है। यदि आप यह निर्धारित करने में सक्षम हैं कि खोज के आउटपुट के लिए किस प्रारूप का उपयोग करना है, तो न्यूलाइन का उपयोग करने की तुलना में टर्मिनेटर के रूप में '\ 0' का उपयोग करना बेहतर है, क्योंकि फ़ाइल नामों में सफेद स्थान और न्यूलाइन वर्ण शामिल हो सकते हैं।

  1. -czvf संग्रह बनाएं, संग्रह को gzip के माध्यम से फ़िल्टर करें, क्रियाशील सूची फ़ाइलों को संसाधित करें, संग्रह नाम

संपादित करें 2019-08-14: मैं यह जोड़ना चाहूंगा, कि मैं अपनी टिप्पणी में अनिवार्य रूप से उसी कमांड का उपयोग करने में सक्षम था, बस खुद को टारगेट करता हूं:

tar -czvf /archiveDir/test.tar.gz --newer-mtime=0 --ignore-failed-read *.pdf

जरूरत --ignore-failed-readके मामले में आज के लिए कोई नया पीडीएफ नहीं था।


1

सबसे अच्छा समाधान एक फ़ाइल सूची बनाना और फिर फ़ाइलों को संग्रह करना प्रतीत होता है क्योंकि आप अन्य स्रोतों का उपयोग कर सकते हैं और सूची के साथ कुछ और कर सकते हैं।

उदाहरण के लिए यह सूची का उपयोग करके फ़ाइलों के आकार की गणना करने की अनुमति देता है:

#!/bin/sh

backupFileName="backup-big-$(date +"%Y%m%d-%H%M")"
backupRoot="/var/www"
backupOutPath=""

archivePath=$backupOutPath$backupFileName.tar.gz
listOfFilesPath=$backupOutPath$backupFileName.filelist

#
# Make a list of files/directories to archive
#
echo "" > $listOfFilesPath
echo "${backupRoot}/uploads" >> $listOfFilesPath
echo "${backupRoot}/extra/user/data" >> $listOfFilesPath
find "${backupRoot}/drupal_root/sites/" -name "files" -type d >> $listOfFilesPath

#
# Size calculation
#
sizeForProgress=`
cat $listOfFilesPath | while read nextFile;do
    if [ ! -z "$nextFile" ]; then
        du -sb "$nextFile"
    fi
done | awk '{size+=$1} END {print size}'
`

#
# Archive with progress
#
## simple with dump of all files currently archived
#tar -czvf $archivePath -T $listOfFilesPath
## progress bar
sizeForShow=$(($sizeForProgress/1024/1024))
echo -e "\nRunning backup [source files are $sizeForShow MiB]\n"
tar -cPp -T $listOfFilesPath | pv -s $sizeForProgress | gzip > $archivePath

इसके लिए एक लाइनर?
रॉबिनो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.