第二次尝试相当接近了,你需要在
test -f
后面加一个空格。
base$ echo '2015|/etc/mtab
> 2015|/etc/ntab' | awk -F\| '{ if (system("test -f " $2)) print $2}'
/etc/ntab
您可能希望倒置使用
if (system(...)==0)
以获得您预期的语义。此外,更为优雅的是,Awk需要在大括号外面设置条件,因此您可以避免明确使用
if
。
awk -F\| 'system("test -f " $2)==0 { print $2 }'
我同意评论者的看法,使用Awk来处理这个问题有点不切实际。
如果像评论中提到的那样,您需要处理任意文件名,您可以添加代码来引用任何特殊的Shell字符:
awk -F\| 'system ("test -f " gensub(/[^\/A-Za-z0-9]/, "\\\\&", "g", $2))==0 {
print $2 }'
...但是您整体的解决方案不能处理包含换行符或管道符号的文件名(因为您将它们分别用作记录和字段分隔符),所以再次放弃Awk并采用不同的方法可能是明智的选择。
(替换中的字符类是不完整的;有各种标点符号等可以添加,我可能会错过一些重要的内容;但是快速检查表明,多余的反斜杠应该是无害的。如果您没有Gawk,请参见此处,或者再次考虑放弃这种方法。)
while IFS='|' read -r stuff filename; do
test -f "$filename" && echo "$filename"
done <<':'
2015|/etc/mtab
2016|/etc/ntab
2017|/path/to/file with whitespace in name
2018|/path/to/file\with[funny"characters*in(file'name|even pipes, you see?
:
(仍然没有换行的方法,但其他方面都应该没问题。)
awk
来完成这件事吗? - Pankrates