如何将文件列表过滤到存在的文件?
例如,
echo 'a.txt
does/not.exist
b.txt' | <???>
Run Code Online (Sandbox Code Playgroud)
会打印
a.txt
b.txt
Run Code Online (Sandbox Code Playgroud)
fed*_*qui 17
你可以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
Run Code Online (Sandbox Code Playgroud)
如您所见,xargs ls -d
执行ls -d
所有给出的参数.2>/dev/null
摆脱stderr消息.
如果您有GNU xargs
,请用于-d '\n'
确保正确处理带有嵌入空格的文件名(包括目录),方法是将输入拆分为整行而不是行内空格。
echo 'a.txt
does/not.exist
b.txt' | xargs -d '\n' ls -1df 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
笔记:
该ls
命令为每个不存在的输入路径发出一个错误,2>/dev/null
忽略,同时按原样回显现有路径。
Option 将-1
每个路径打印在自己的行上,-d
防止递归到目录中,并-f
防止对输入路径进行排序(如果您确实想要排序,请省略f
)。
上的MacOS / BSD,xargs
不支持-d
,这需要经由使用NUL分隔输入一种变通方法tr
和xargs
的-0
选项:
echo 'a.txt
does/not.exist
b.txt' | tr '\n' '\0' | xargs -0 ls -1df 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
小智 5
作为一句单行话,纯粹的速度打击(从 mklement0 的答案改进,如果我有代表,我会发表评论):
{ ls; echo does/not.exist; } | while IFS= read -r f; do [[ -f "$f" ]] && echo "$f"; done
Run Code Online (Sandbox Code Playgroud)