awk 检查文件是否存在

pep*_*co2 5 unix awk file

printf "2015-03-02|/home/user/.ssh/config\n2015-03-02|/home/user/Desktop/temp328\n" | awk -F\| 'if ( -f $2 )  { print $2}'
Run Code Online (Sandbox Code Playgroud)

或者

printf "2015-03-02|/home/user/.ssh/config\n2015-03-02|/home/user/Desktop/temp328\n" | awk -F\| '{if (system("test -f" $2)) print $2}'
Run Code Online (Sandbox Code Playgroud)

/home/user/.ssh/config\n2015-03-02 - 存在

/home/user/Desktop/temp328 - 已删除

我只想打印存在的文件,但此命令不起作用。

tri*_*eee 5

第二次尝试相当接近。后需要一个空格test -f

base$ echo '2015|/etc/mtab
> 2015|/etc/ntab' | awk -F\| '{ if (system("test -f " $2)) print $2}'
/etc/ntab
Run Code Online (Sandbox Code Playgroud)

您可能想要反转使用if (system(...)==0)来获得您期望的语义。此外,更优雅一点的是,Awk 希望在大括号之外有一个条件,因此您可以避免显式的if.

awk -F\| 'system("test -f " $2)==0 { print $2 }'
Run Code Online (Sandbox Code Playgroud)

同意评论者的意见,即为此使用 awk 是极端的坚果。

如果,如注释中所示,您需要使用完全任意的文件名,您可以添加代码来引用任何 shell 特殊内容:

awk -F\| 'system ("test -f " gensub(/[^\/A-Za-z0-9]/, "\\\\&", "g", $2))==0 {
   print $2 }'   # caveat: gensub() is gawk only
Run Code Online (Sandbox Code Playgroud)

...但您的整体解决方案无法处理包含换行符或管道符的文件名(因为您分别将它们用作记录和字段分隔符)所以再次放弃 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?
:
Run Code Online (Sandbox Code Playgroud)

(仍然没有办法换行,但其他一切都应该没问题。)


Jam*_*own 5

使用 GNU awk,您可以使用stat()包含在filefuncs扩展中的内容:

$ ls -l 
-rw-r--r-- 1 james james 4 Oct  3 12:48 foo
-rw------- 1 root  root  0 Oct  3 12:48 bar
Run Code Online (Sandbox Code Playgroud)

awk:

$ awk -v file=foo '
@load "filefuncs"
BEGIN {
    ret=stat(file,fdata)
    printf "ret:  %d\nsize: %d\n",ret,fdata["size"]
}'
Run Code Online (Sandbox Code Playgroud)

输出-v file= foo

ret:  0
size: 4
Run Code Online (Sandbox Code Playgroud)

为了bar

ret:  0
size: 0
Run Code Online (Sandbox Code Playgroud)

对于不存在的baz

ret:  -1
size: 0
Run Code Online (Sandbox Code Playgroud)