如何将文件列表过滤到现有文件?
例如,
echo 'a.txt
does/not.exist
b.txt' | <???>
会打印
a.txt
b.txt
答案 0 :(得分:14)
您可以ls -d
这些文件并查看哪些文件获得了一些输出。由于您在字符串中包含这些内容,因此只需管道列表并使用xargs
即可ls
。
要隐藏错误,请将这些错误重定向到/dev/null
。总之,xargs ls -d 2>/dev/null
使它成为:
$ echo 'a.txt
b.txt
other' | xargs ls -d 2>/dev/null
a.txt
b.txt
如您所见,xargs ls -d
对所有给出的参数执行ls -d
。 2>/dev/null
摆脱了stderr消息。
答案 1 :(得分:2)
如果你有 GNU xargs
,请使用-d '\n'
确保正确处理带有嵌入空格的文件名。
$ echo 'a.txt
does/not.exist
b.txt' | xargs -d '\n' find 2>/dev/null
使用BSD / macOS xargs
,它有点复杂:
echo 'a.txt
does/not.exist
b.txt' | tr '\n' '\0' | xargs -0 find 2>/dev/null
答案 2 :(得分:0)
我想出了第一件事,在while循环中使用stats
的退出代码:
<input> | while IFS= read -r f; do stat "$f" &>/dev/null && echo "$f"; done
请注意,此解决方案是慢,因为它在shell代码中循环,并调用
外部实用程序(在每次迭代中创建子进程stat
)。
答案 3 :(得分:0)
我会使用bash来检查文件。它最终变得不那么紧凑,但我认为它更清晰,并且更容易对结果中的每个找到的文件做一些事情。
它与带空格的文件名兼容。
echo 'a.txt
does/not.exist
b.txt' | while read filename
do
if [[ -f "$filename" ]]
then
echo $filename # Or do something else with the files here
fi
done
答案 4 :(得分:0)
作为一个单线,纯正的打击速度(从mklement0的答案中得到改善,如果我有代表的话会发表评论):
{ ls; echo does/not.exist; } | while IFS= read -r f; do [[ -f "$f" ]] && echo "$f"; done