Trova i file e incollali (con spazi)

Va bene, problema così semplice qui. Sto lavorando su un semplice codice di backup. Funziona bene, tranne se i file contengono spazi. Ecco come sto trovando i file e aggiungendoli a un archivio tar:

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

Il problema è quando il file ha uno spazio nel nome perché tar crede che sia una cartella. Fondamentalmente c’è un modo per aggiungere citazioni ai risultati di find? O un modo diverso per risolvere questo problema?

Usa questo:

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

Lo farà:

  • trattare con file con spazi, newline, trattini principali e altre funnance
  • gestire un numero illimitato di file
  • non sovrascriverà ripetutamente il tuo backup.tar.gz come usare tar -c con xargs lo farà quando hai un gran numero di file

Vedi anche:

  • Manuale di tar GNU
  • Come posso build un tar dallo stdin? , cerca nullo

Potrebbe esserci un altro modo per ottenere quello che vuoi. Fondamentalmente,

  1. Usa il comando find per inviare il percorso a qualunque file tu stia cercando. Reindirizza lo stdout su un nome file di tua scelta.
  2. Quindi tar con l’opzione -T che gli consente di prendere una lista di posizioni dei file (quella che hai appena creato con find!)

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

Prova a correre:

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

Perchè no:

 tar czvf backup.tar.gz * 

Certo è intelligente usare find e poi xargs, ma lo stai facendo nel modo più duro.

Aggiornamento: Porges ha commentato con un’opzione di ricerca che ritengo sia una risposta migliore della mia risposta, o l’altra: find -print0 ... | xargs -0 .... find -print0 ... | xargs -0 ....

Se si dispone di più file o directory e si desidera comprimerli in un file *.gz indipendente, è ansible farlo. Opzionale -type f -atime

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

Questo comprimerà

 httpd-log01.txt httpd-log02.txt 

a

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

Perché non dare una prova del genere: tar cvf scala.tar `find src -name *.scala`

Un’altra soluzione come visto qui :

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

La soluzione migliore sembra essere quella di creare un elenco di file e quindi di archiviare i file perché è ansible utilizzare altre fonti e fare qualcos’altro con l’elenco.

Ad esempio ciò consente di utilizzare l’elenco per calcolare la dimensione dei file da archiviare:

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