概述
好吧,这么简单的问题。我正在编写一个简单的备份代码。它工作得很好,除非文件中有空格。以下是我查找文件并将其添加到tar存档的方式:
find . -type f | xargs tar -czvf backup.tar.gz
问题是当文件名中有空间时,因为tar认为它是一个文件夹。基本上,有没有一种方法可以在find的结果周围添加引号?或者用另一种方法来解决这个问题?
使用find ... | xargs ...的最佳方法是在每个:find -print0 ... | xargs -0 ...上使用-print0/-0参数。这将导致文件名被一个空字符分隔,这意味着文件名中可以有空格、换行符或其他奇怪的内容,而且它仍然有效。
这样使用xargs和tar有一个问题:当您有大量文件时,xargs将重复调用tar-c,这将不断覆盖您的归档文件,结果是您不会拥有您期望的所有文件。请参阅下面更详细的解释和我的答案。
使用此:
find . -type f -print0 | tar -czvf backup.tar.gz --null -T -
它将:
处理带有空格、换行符、前导破折号和其他功能的文件
处理无限数量的文件
不会重复覆盖backup.tar.gz,就像在xargs中使用tar -c一样,当您有大量文件时会这样做。
还可以看到:
GNU沥青手册
我怎样才能从stdin构建一个tar?,搜索空值
如果你想先把你的发现通过SED传输几次,你会怎么做?例如查找。-打印0 SED/备份/D tar….
请注意,如果有多个条件,则需要添加括号。否则,-print0仅适用于最后一个表达式。如find . ( -type f -o -name '*.c' ) -print0 | ...。
为了好玩,这里有一个使用cygwin的windows版本:c:cygwinbinfind . -regextype posix-egrep -regex '.*(sln^|vcxproj^|filters)$' -print0 | c:cygwinbintar -cvf MS_Projects.tar --null -T -
@史蒂夫,你能解释一下在tar命令末尾的"-"选项吗?我在GNU TAR的主页上找不到它。
当然,它是-T的一个参数,它的意思是从标准输入中读取文件名:如果为`--file s from',(即,指定--files from=-或-t-)指定一个破折号作为文件名,则从标准输入中读取文件名。
--null是什么?
@tommy.carstensen它处理由-print0arg生成的以空分隔的文件名到find,这使得所有这些都能够处理带有空格、换行符等的文件名。
还有另一种方法可以实现你想要的。基本上,
使用find命令将路径输出到您要查找的任何文件。将stdout重定向到您选择的文件名。
然后使用-t选项tar,该选项允许它获取文件位置列表(使用find!创建的位置)。
find . -name"*.whatever"> yourListOfFiles
tar -cvf yourfile.tar -T yourListOfFiles
这对换行的文件名无效
这里有一个关于如何用换行符处理文件名的答案:superuser.com/a/513319/151261
试运行:
find . -type f | xargs -d"
" tar -czvf backup.tar.gz
为什么不:
tar czvf backup.tar.gz *
当然,先使用find,然后使用xargs是很聪明的,但这是很难做到的。
更新:Porges评论说,我认为一个查找选项比我的答案更好,或者另一个:find -print0 ... | xargs -0 ....。
我的完整代码将只备份在过去一天中修改过的项目。因为它是每日备份,所以我不想重复保存文件大小的信息(我也每15天进行一次完整备份)。
为了使这个问题更好,我会问一个关于"可靠地同时使用find、xargs和tar"的问题。您的标题和问题并没有真正指定您需要查找和xargs,但您确实需要。
如果文件列表太长,xargs ... tar c ...将覆盖创建的第一个存档,xargs将第二次执行tar!为了避免覆盖,您可以使用xargs -x,但是归档可能不完整。另一种可能是先使用tar c ...,然后可能重复使用tar r ...。(我对可靠性的贡献:)
如果您有多个文件或目录,并且希望将它们压缩到独立的*.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
另一个解决方案如下所示:
find var/log/ -iname"anaconda.*" -exec tar -cvzf file.tar.gz {} +
为什么不试试这样的东西:tar cvf scala.tar `find src -name *.scala`。
最好的解决方案似乎是创建一个文件列表,然后存档文件,因为您可以使用其他源并对该列表执行其他操作。
例如,这允许使用列表计算正在存档的文件的大小:
#!/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
一个内衬?
最后
以上就是无情火龙果为你收集整理的linux查找文件中空格及,关于linux:查找文件并对它们进行tar(带空格)的全部内容,希望文章能够帮你解决linux查找文件中空格及,关于linux:查找文件并对它们进行tar(带空格)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复