好了,这里的问题很简单。我正在研究一个简单的备份代码。除非文件中有空格,否则它工作正常。这就是我查找文件并将其添加到tar存档中的方式:
find . -type f | xargs tar -czvf backup.tar.gz
问题是文件名中有空格时,因为tar认为它是文件夹。基本上有没有一种方法可以在find的结果周围添加引号?还是其他解决方法?
好了,这里的问题很简单。我正在研究一个简单的备份代码。除非文件中有空格,否则它工作正常。这就是我查找文件并将其添加到tar存档中的方式:
find . -type f | xargs tar -czvf backup.tar.gz
问题是文件名中有空格时,因为tar认为它是文件夹。基本上有没有一种方法可以在find的结果周围添加引号?还是其他解决方法?
Answers:
用这个:
find . -type f -print0 | tar -czvf backup.tar.gz --null -T -
它会:
tar -c
,xargs
不会像使用with 那样反复覆盖您的backup.tar.gz另请参阅:
-print0
仅适用于最后一个表达式。例如find . \( -type f -o -name '*.c' \) -print0 | ...
c:\cygwin\bin\find . -regextype posix-egrep -regex '.*(sln^|vcxproj^|filters)$' -print0 | c:\cygwin\bin\tar -cvf MS_Projects.tar --null -T -
-T
,它意味着从标准输入中读取文件名:如果您将单破折号作为`--files-from'的文件名,(即,您指定了--files-from = -或
可能会有另一种方式来实现您想要的。基本上,
然后使用带有-T选项的tar,该选项允许它获取文件位置的列表(您刚刚使用find创建的位置!)
find . -name "*.whatever" > yourListOfFiles
tar -cvf yourfile.tar -T yourListOfFiles
为什么不:
tar czvf backup.tar.gz *
确保先使用find然后再使用xargs是明智的选择,但是您很难做到这一点。
更新:Porges评论了一个find-option,我认为这是比我的答案更好的答案,或者另外一个: find -print0 ... | xargs -0 ....
xargs ... tar c ...
如果文件列表过长,将覆盖创建的第一个归档文件,xargs
并将tar
第二次执行!为了避免覆盖,可以使用,xargs -x
但是存档可能不完整。替代方案可以是先进行tar c ...
,然后可能反复进行tar r ...
。(我对可靠性的贡献:)
将在@Steve Kehlet帖子中添加评论,但需要50个代表(RIP)。
对于通过大量谷歌搜索找到此帖子的任何人,我都找到了一种方法,不仅可以找到给定时间范围内的特定文件,而且还不包括可能导致标定错误的相对路径或空格。(非常感谢您。)
find . -name "*.pdf" -type f -mtime 0 -printf "%f\0" | tar -czvf /dir/zip.tar.gz --null -T -
.
相对目录
-name "*.pdf"
查找pdf(或任何文件类型)
-type f
要查找的类型是文件
-mtime 0
查找最近24小时内创建的文件
-printf "%f\0"
常规-print0
或-printf "%f"
不适用于我。从手册页:
引用的执行方式与GNU ls相同。这与用于-ls和-fls的引用机制不同。如果您能够决定用于find输出的格式,那么通常最好使用'\ 0'作为终止符,而不是使用换行符,因为文件名可以包含空格和换行符。
-czvf
创建档案,通过gzip过滤档案,详细列出已处理的文件,档案名称编辑2019-08-14:我想补充一点,我也能够在评论中使用基本上相同的命令,只是使用tar本身:
tar -czvf /archiveDir/test.tar.gz --newer-mtime=0 --ignore-failed-read *.pdf
需要--ignore-failed-read
在情况有今天没有新的PDF文件。
最好的解决方案似乎是先创建文件列表,然后再归档文件,因为您可以使用其他来源并对列表进行其他操作。
例如,这允许使用列表来计算要归档的文件的大小:
#!/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
find ... | xargs ...
是在每个上使用-print0 / -0参数find -print0 ... | xargs -0 ...
。这将导致文件名由空字符分隔,这意味着您可以在文件名中包含空格,换行符或其他奇怪的内容,并且仍然可以使用。