it-swarm.com.de

Dateien finden und tarieren (mit Leerzeichen)

Okay, so einfaches Problem hier. Ich arbeite an einem einfachen Sicherungscode. Es funktioniert einwandfrei, außer wenn die Dateien Leerzeichen enthalten. So finde ich Dateien und füge sie einem tar-Archiv hinzu:

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

Das Problem ist, wenn die Datei ein Leerzeichen im Namen enthält, weil tar denkt, dass es sich um einen Ordner handelt. Gibt es eine Möglichkeit, die Ergebnisse von find in Anführungszeichen zu setzen? Oder eine andere Möglichkeit, dies zu beheben?

106
Caleb Kester

Benutze das:

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

Es wird:

  • befassen sich mit Dateien mit Leerzeichen, Zeilenumbrüchen, Bindestrichen und anderen lustigen Elementen
  • behandeln Sie eine unbegrenzte Anzahl von Dateien
  • überschreiben Sie Ihre Datei backup.tar.gz nicht mehrmals wie mit tar -c mit xargs reicht aus, wenn Sie eine große Anzahl von Dateien haben

Siehe auch:

205
Steve Kehlet

Es könnte einen anderen Weg geben, um das zu erreichen, was Sie wollen. Grundsätzlich gilt,

  1. Verwenden Sie den Befehl find, um den Pfad zu den gesuchten Dateien auszugeben. Leiten Sie stdout zu einem Dateinamen Ihrer Wahl um.
  2. Dann tar mit der Option -T, mit der eine Liste der Dateispeicherorte erstellt werden kann (der, den Sie gerade mit find erstellt haben!)

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

Versuche es mit:

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

Warum nicht:

tar czvf backup.tar.gz *

Sicher, es ist klug, find und dann xargs zu verwenden, aber Sie tun es auf die harte Tour.

Update: Porges hat mit einer Suchoption kommentiert, die meiner Meinung nach eine bessere Antwort ist als meine oder die andere: find -print0 ... | xargs -0 ....

7
Warren P

Wenn Sie mehrere Dateien oder Verzeichnisse haben und diese in unabhängige *.gz Datei können Sie dies tun. Wahlweise -type f -atime

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

Dies wird komprimiert

httpd-log01.txt
httpd-log02.txt

zu

httpd-log01.txt.gz
httpd-log02.txt.gz
3
Kalibur x

Warum probieren Sie nicht so etwas aus: tar cvf scala.tar `find src -name *.scala`

2
Frank Eggink

Eine andere Lösung wie gesehen hier :

find var/log/ -iname "anaconda.*" -exec tar -cvzf file.tar.gz {} +
2

Füge einen Kommentar zu @ Steve Kehlet post hinzu, benötige aber 50 Wiederholungen (RIP).

Für jeden, der diesen Beitrag durch zahlreiche Google-Versuche gefunden hat, habe ich eine Möglichkeit gefunden, nicht nur bestimmte Dateien in einem bestimmten Zeitbereich zu finden, sondern auch NICHT die relativen Pfade OR Leerzeichen, die zu Teerungsfehlern führen würden. (DANKE SO VIEL STEVE.)

find . -name "*.pdf" -type f -mtime 0 -printf "%f\0" | tar -czvf /dir/Zip.tar.gz --null -T -
  1. . relatives Verzeichnis

  2. -name "*.pdf" Suche nach pdfs (oder einem beliebigen Dateityp)

  3. -type f Typ zu suchen ist eine Datei

  4. -mtime 0 nach Dateien suchen, die in den letzten 24 Stunden erstellt wurden

  5. -printf "%f\0" Regular -print0 OR -printf "%f" hat NICHT für mich gearbeitet. Aus Manpages:

Dieses Zitieren wird auf dieselbe Weise durchgeführt wie für GNU ls. Dies ist nicht derselbe Zitiermechanismus wie für -ls und -fls. Wenn Sie entscheiden können, welches Format verwendet werden soll Für die Ausgabe von find ist es normalerweise besser, '\ 0' als Abschlusszeichen zu verwenden, als Newline, da Dateinamen Leerzeichen und Newline-Zeichen enthalten können.

  1. -czvf Archiv erstellen, Archiv nach gzip filtern, verarbeitete Dateien ausführlich auflisten, Archivname

Edit 2019-08-14: Ich möchte hinzufügen, dass ich im Wesentlichen den gleichen Befehl in meinem Kommentar verwenden konnte, nur mit tar selbst:

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

Erforderlich --ignore-failed-read falls es heute keine neuen PDFs gab.

1
user3472383

Die beste Lösung scheint darin zu bestehen, eine Dateiliste zu erstellen und die Dateien dann zu archivieren, da Sie andere Quellen verwenden und etwas anderes mit der Liste tun können.

So können Sie beispielsweise anhand der Liste die Größe der zu archivierenden Dateien berechnen:

#!/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
1
Nux