Find files and tar them (with spaces)
好吧,这么简单的问题。我正在编写一个简单的备份代码。它工作得很好,除非文件中有空格。以下是我查找文件并将其添加到tar存档的方式:
1 | find . -type f | xargs tar -czvf backup.tar.gz |
问题是当文件名中有空间时,因为tar认为它是一个文件夹。基本上,有没有一种方法可以在find的结果周围添加引号?或者用另一种方法来解决这个问题?
使用此:
1 | find . -type f -print0 | tar -czvf backup.tar.gz --null -T - |
它将:
- 处理带有空格、换行符、前导破折号和其他功能的文件
- 处理无限数量的文件
- 不会重复覆盖backup.tar.gz,就像在
xargs 中使用tar -c 一样,当您有大量文件时会这样做。
还可以看到:
- GNU沥青手册
- 我怎样才能从stdin构建一个tar?,搜索空值
还有另一种方法可以实现你想要的。基本上,
然后使用-t选项tar,该选项允许它获取文件位置列表(使用find!创建的位置)。
1 2 | find . -name"*.whatever"> yourListOfFiles tar -cvf yourfile.tar -T yourListOfFiles |
试运行:
1 2 | find . -type f | xargs -d" " tar -czvf backup.tar.gz |
为什么不:
1 | tar czvf backup.tar.gz * |
当然,先使用find,然后使用xargs是很聪明的,但这是很难做到的。
更新:Porges评论说,我认为一个查找选项比我的答案更好,或者另一个:
如果您有多个文件或目录,并且希望将它们压缩到独立的
1 | find -name"httpd-log*.txt" -type f -mtime +1 -exec tar -vzcf {}.gz {} \; |
这会压缩
1 2 | httpd-log01.txt httpd-log02.txt |
到
1 2 | httpd-log01.txt.gz httpd-log02.txt.gz |
另一个解决方案如下所示:
1 | find var/log/ -iname"anaconda.*" -exec tar -cvzf file.tar.gz {} + |
为什么不试试这样的东西:
最好的解决方案似乎是创建一个文件列表,然后存档文件,因为您可以使用其他源并对该列表执行其他操作。
例如,这允许使用列表计算正在存档的文件的大小:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #!/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" Running backup [source files are $sizeForShow MiB] " tar -cPp -T $listOfFilesPath | pv -s $sizeForProgress | gzip > $archivePath |