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

时间:2014-01-14 16:46:13

标签: bash file

如何将文件列表过滤到现有文件?

例如,

echo 'a.txt
does/not.exist
b.txt' | <???>

会打印

a.txt
b.txt 

5 个答案:

答案 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 -d2>/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