将文件列表过滤到存在的文件

Pau*_*per 15 bash file

如何将文件列表过滤到存在的文件?

例如,

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消息.

  • ...关于解析`ls`输出的常见警告; 例如,如果其中一个参数是目录,您将获得目录的内容,而不是其名称. (3认同)
  • 好的,也许`ls -d`会是最好的. (2认同)

mkl*_*nt0 5

如果您有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分隔输入一种变通方法trxargs-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)