如何通过查找返回的文件名循环? [英] How to loop through file names returned by find?
问题描述
x=$(find . -name "*.txt")
echo $x
如果我运行的Bash shell上面这段code的,我所得到的是包含空白,而不是一个列表分隔的多个文件名的字符串。
if I run the above piece of code in Bash shell, what I get is a string containing several file names separated by blank, not a list.
当然,我还可以通过空白分开它们得到一个清单,但我敢肯定有更好的方式来做到这一点。
Of course, I can further separate them by blank to get a list, but I'm sure there is a better way to do it.
那么,什么是要通过找到
命令?
So what is the best way to loop through the results of a find
command?
推荐答案
TL; DR:如果你只是在这里是最正确的答案,你可能想我个人的preference,找到。 -name* .TXT-exec过程{} \\;
(看到这个帖子的底部)。如果你有时间,通读其余看到几种不同的方式和问题,其中的大多数。
TL;DR: If you're just here for the most correct answer, you probably want my personal preference, find . -name '*.txt' -exec process {} \;
(see the bottom of this post). If you have time, read through the rest to see several different ways and the problems with most of them.
完整的答案是:
最好的方法取决于你想做的事,但这里有几个选项。只要子树没有文件或文件夹中有空格的名称中,你可以通过文件循环:
The best way depends on what you want to do, but here are a few options. As long as no file or folder in the subtree has whitespace in its name, you can just loop over the files:
for i in $x; do # Not recommended, will break on whitespace
process "$i"
done
略好,切出的临时变量 X
:
for i in $(find -name \*.txt); do # Not recommended, will break on whitespace
process "$i"
done
是多的更好时,你可以给glob的。白色空间安全的,文件在当前目录:
It is much better to glob when you can. White-space safe, for files in the current directory:
for i in *.txt; do # Whitespace-safe but not recursive.
process "$i"
done
通过启用 globstar
选项,您可以使用通配此目录中所有匹配的文件和所有子目录:
By enabling the globstar
option, you can glob all matching files in this directory and all subdirectories:
# Make sure globstar is enabled
shopt -s globstar
for i in **/*.txt; do # Whitespace-safe and recursive
process "$i"
done
在一些情况下,例如如果文件名都已经是一个文件,你可能需要使用读
:
In some cases, e.g. if the file names are already in a file, you may need to use read
:
# IFS= makes sure it doesn't trim leading and trailing whitespace
# -r prevents interpretation of \ escapes.
while IFS= read -r line; do # Whitespace-safe EXCEPT newlines
process "$line"
done < filename
读
可以用安全使用组合找到
通过适当地设置分隔符:
read
can be used safely in combination with find
by setting the delimiter appropriately:
find . -name '*.txt' -print0 |
while IFS= read -r -d $'\0' line; do
process $line
done
有关更复杂的搜索,你可能会想使用找到
,无论是与它的 -exec
选项或 -print0 | xargs的-0
:
For more complex searches, you will probably want to use find
, either with its -exec
option or with -print0 | xargs -0
:
# execute `process` once for each file
find . -name \*.txt -exec process {} \;
# execute `process` once with all the files as arguments*:
find . -name \*.txt -exec process {} +
# using xargs*
find . -name \*.txt -print0 | xargs -0 process
# using xargs with arguments after each filename (implies one run per filename)
find . -name \*.txt -print0 | xargs -0 -I{} process {} argument
找到
也可以cd到每一个文件的目录通过运行一个命令之前 -execdir
而不是<$ C的$ C> -exec ,并可以进行交互使用(每个文件运行命令提示符之前) -ok
而不是 -exec
(或 -okdir
而不是 -execdir
)。
find
can also cd into each file's directory before running a command by using -execdir
instead of -exec
, and can be made interactive (prompt before running the command for each file) using -ok
instead of -exec
(or -okdir
instead of -execdir
).
*:从技术上讲,这两个找到
和的xargs
(默认)将运行带有多个参数的命令他们能够适应在命令行中,多次因为它需要通过所有的文件来获得。在实践中,除非你有一个非常大的数字文件,也没有关系,如果你超出了长度,但需要他们都是一样的命令行上,你SOL 找到一个不同的方式。
*: Technically, both find
and xargs
(by default) will run the command with as many arguments as they can fit on the command line, as many times as it takes to get through all the files. In practice, unless you have a very large number of files it won't matter, and if you exceed the length but need them all on the same command line, you're SOL find a different way.
这篇关于如何通过查找返回的文件名循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!