查找文件并压缩它们(带空格)
好吧,问题就这么简单。我正在编写一个简单的备份代码。除非文件中有空格,否则它工作正常。这就是我查找文件并将它们添加到 tar 存档的方式:
find . -type f | xargs tar -czvf backup.tar.gz
问题是文件名称中包含空格,因为 tar 认为它是一个文件夹。基本上有没有一种方法可以在 find 的结果周围添加引号?或者有不同的方法来解决这个问题?
Alright, so simple problem here. I'm working on a simple back up code. It works fine except if the files have spaces in them. This is how I'm finding files and adding them to a tar archive:
find . -type f | xargs tar -czvf backup.tar.gz
The problem is when the file has a space in the name because tar thinks that it's a folder. Basically is there a way I can add quotes around the results from find? Or a different way to fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
为什么不呢:
当然,使用 find 然后使用 xargs 是很聪明的做法,但是你这样做很困难。
更新:Porges 评论了一个查找选项,我认为这是一个比我的答案更好的答案,或者另一个:
find -print0 ... | xargs -0 ....
Why not:
Sure it's clever to use find and then xargs, but you're doing it the hard way.
Update: Porges has commented with a find-option that I think is a better answer than my answer, or the other one:
find -print0 ... | xargs -0 ....
如果您有多个文件或目录,并且想要将它们压缩成独立的
*.gz
文件,您可以这样做。可选-type f -atime
这将压缩
为
If you have multiple files or directories and you want to zip them into independent
*.gz
file you can do this. Optional-type f -atime
This will compress
to
将向 @Steve Kehlet 帖子 添加评论,但需要 50 次代表 (RIP)。
对于通过大量谷歌搜索找到这篇文章的人,我找到了一种方法,不仅可以找到给定时间范围的特定文件,而且不包含会导致焦距错误的相对路径或空格。 (非常感谢史蒂夫。)
.
相对目录-name "*.pdf" 查找 pdf(或任何文件类型)
-type f
键入要查找的文件-mtime 0
查找过去 24 小时内创建的文件-printf "%f\0"
常规-print0
或-printf "%f"
代码> 对我不起作用。来自手册页:-czvf
创建存档,通过 gzip 过滤存档,详细列出已处理的文件,存档名称编辑 2019-08-14:
我想补充一点,我还可以在评论中使用相同的命令,只需使用 tar 本身:
需要
--ignore-failed-read
以防没有新的 PDF今天。Would add a comment to @Steve Kehlet post but need 50 rep (RIP).
For anyone that has found this post through numerous googling, I found a way to not only find specific files given a time range, but also NOT include the relative paths OR whitespaces that would cause tarring errors. (THANK YOU SO MUCH STEVE.)
.
relative directory-name "*.pdf"
look for pdfs (or any file type)-type f
type to look for is a file-mtime 0
look for files created in last 24 hours-printf "%f\0"
Regular-print0
OR-printf "%f"
did NOT work for me. From man pages:-czvf
create archive, filter the archive through gzip , verbosely list files processed, archive nameEdit 2019-08-14:
I would like to add, that I was also able to use essentially use the same command in my comment, just using tar itself:
Needed
--ignore-failed-read
in-case there were no new PDFs for today.为什么不尝试一下这样的事情:
tar cvf scala.tar `find src -name *.scala`
Why not give something like this a try:
tar cvf scala.tar `find src -name *.scala`
此处所示的另一个解决方案:
Another solution as seen here:
最好的解决方案似乎是创建一个文件列表,然后归档文件,因为您可以使用其他源并对列表执行其他操作。
例如,这允许使用列表来计算正在归档的文件的大小:
The best solution seem to be to create a file list and then archive files because you can use other sources and do something else with the list.
For example this allows using the list to calculate size of the files being archived:
对几个解决方案(以及您自己的测试)的重大警告:
当您这样做时:任何事情| xargs some
xargs 会尝试在“something”之后容纳“尽可能多的参数”,但最终可能会多次调用“something”。
所以你的尝试:找到... | xargs tar czvf 文件.tgz
可能最终会在 xargs 每次调用“tar”时覆盖“file.tgz”,并且最终只有最后一次调用! (所选择的解决方案使用 GNU -T 特殊参数来避免该问题,但并非每个人都有可用的 GNU tar)
您可以这样做:
cygwin 上的问题证明:
注意:xargs 的行为是众所周知的 diccifulty,并且这也是为什么,当有人想要这样做时:
他们必须这样写:
这样,即使 xargs 最后一次调用 grep 仅附加 1 个文件名,grep 至少会看到 2 个文件名(因为每次它都有:
/dev/null
,它不会找到任何东西,并且在其后附加 xargs 的文件名
),因此当某些内容匹配“regex”时,将始终显示文件名”。否则,最后的结果可能会显示前面没有文件名的匹配项。Big warning on several of the solutions (and your own test) :
When you do : anything | xargs something
xargs will try to fit "as many arguments as possible" after "something", but then you may end up with multiple invocations of "something".
So your attempt: find ... | xargs tar czvf file.tgz
may end up overwriting "file.tgz" at each invocation of "tar" by xargs, and you end up with only the last invocation! (the chosen solution uses a GNU -T special parameter to avoid the problem, but not everyone has that GNU tar available)
You could do instead:
Proof of the problem on cygwin:
Note: that behavior of xargs is a well know diccifulty, and it is also why, when someone wants to do :
they intead have to write it:
That way, even if the last invocation of grep by xargs appends only 1 filename, grep sees at least 2 filenames (as each time it has:
/dev/null
, where it won't find anything, andthe filename(s)
appended by xargs after it) and thus will always display the file names when something maches "regex". Otherwise you may end up with the last results showing matches without a filename in front.使用这个:
它将:
tar -c
那样重复覆盖您的 backup.tar.gz当您有大量文件时,xargs
即可。另请参阅:
Use this:
It will:
tar -c
withxargs
will do when you have a large number of filesAlso see:
可能还有另一种方法可以实现您想要的目标。基本上,
然后使用 -T 选项进行 tar,这允许它获取文件位置列表(您刚刚使用 find 创建的位置!)
<前><代码>查找 . -名称“*.whatever”>你的文件列表
tar -cvf yourfile.tar -T yourListOfFiles
There could be another way to achieve what you want. Basically,
Then tar with the -T option which allows it to take a list of file locations (the one you just created with find!)
尝试运行:
Try running: