x=$(find . -name "*.txt")
echo $x
如果我在Bash shell中运行上面的代码段,我得到的是一个包含几个由空白分隔的文件名的字符串,而不是一个列表。
当然,我可以进一步用空白分隔它们以得到一个列表,但我相信有更好的方法来做到这一点。
那么,循环查找命令结果的最佳方法是什么呢?
x=$(find . -name "*.txt")
echo $x
如果我在Bash shell中运行上面的代码段,我得到的是一个包含几个由空白分隔的文件名的字符串,而不是一个列表。
当然,我可以进一步用空白分隔它们以得到一个列表,但我相信有更好的方法来做到这一点。
那么,循环查找命令结果的最佳方法是什么呢?
当前回答
你可以把find返回的文件名放入这样一个数组:
array=()
while IFS= read -r -d ''; do
array+=("$REPLY")
done < <(find . -name '*.txt' -print0)
现在,您可以循环遍历数组以访问单个项,并对它们做任何您想做的事情。
注意:它是空白安全的。
其他回答
# Doesn't handle whitespace
for x in `find . -name "*.txt" -print`; do
process_one $x
done
or
# Handles whitespace and newlines
find . -name "*.txt" -print0 | xargs -0 -n 1 process_one
如果你可以假设文件名不包含换行符,你可以使用以下命令将find的输出读入Bash数组:
readarray -t x < <(find . -name '*.txt')
注意:
-t导致readarray删除换行符。 如果readarray在管道中,它将不起作用,因此需要进行进程替换。 readarray从Bash 4开始就可用了。
Bash 4.4及更高版本还支持-d参数来指定分隔符。使用空字符而不是换行符来分隔文件名也适用于文件名包含换行符的罕见情况:
readarray -d '' x < <(find . -name '*.txt' -print0)
Readarray也可以作为具有相同选项的mapfile调用。
参考:https://mywiki.wooledge.org/BashFAQ/005 # Loading_lines_from_a_file_or_stream
查找<path> -xdev -type f -name *.txt -exec ls -l {} \;
这将列出文件并给出有关属性的详细信息。
如果使用grep而不是find呢?
ls | grep .txt$ > out.txt
现在您可以读取这个文件,文件名以列表的形式出现。
find . -name "*.txt"|while read fname; do
echo "$fname"
done
注意:此方法和bmargulies所示的(第二个)方法在文件/文件夹名称中使用空白时是安全的。
为了在文件/文件夹名称中包含换行符,你必须使用find的-exec谓词,就像这样:
find . -name '*.txt' -exec echo "{}" \;
{}是找到的项的占位符,\;用于终止-exec谓词。
为了完整起见,让我添加另一个变体-你必须喜欢*nix的多功能性:
find . -name '*.txt' -print0|xargs -0 -n 1 echo
这将使用\0字符分隔打印项,据我所知,在任何文件系统的文件或文件夹名称中都不允许使用\0字符,因此应该涵盖所有基础。Xargs一个接一个地把它们捡起来,然后……