如何使用文件名或路径中的通配符检查awk中文件是否存在并且不为空

时间:2019-05-22 20:21:35

标签: awk

我正在尝试创建一条小awk行,该行应经过几个路径,并在每个路径中找到一个不应为空的特定文件(通配符)。如果找不到文件或为空,则应打印“ NULL”。 我在stackoverflow和其他地方进行了搜索,但无法真正使它工作。

示例:路径为/ home / test [1..5] /test.json

awk -F"[{}]" '{ if (system("[ ! -f FILENAME ]") == 0 && NR > 0 && NF > 0) print $2; else print "NULL"}' /home/test*/test.txt

如果test.txt为空或不存在,则应打印“ NULL”,但同时不为空时,应打印$ 2。

在上面的示例中,它将仅跳过空文件,而不写“ NULL”!

示例执行/ home /具有test1,test2,test3路径,并且每个路径具有一个test.txt(/home/test1/test.txt为空):

每个/ home / test *路径中的test.txt文件将为空或以下类型的文本(总是一行): {“ test”:1033}

# awk -F"[{}]" '{ if (system("[ ! -f FILENAME ]") == 0 && NR > 0 && NF > 0) print $2; else print "NULL"}' /home/test*/test.txt
"test":1033
"test":209

文件示例:

/home/test0/test.txt (not empty -> {"test":1033})
/home/test1/test.txt (empty)
/home/test2/test.txt (not empty -> {"test":209})
/home/test3/test.txt (not exist)

但是对于../test1/test.txt,我希望看到“ NULL”,但是却什么也看不到!

我希望打印出如下内容:

"test":1033
NULL
"test":209
NULL

我在做什么错了?

BR

2 个答案:

答案 0 :(得分:1)

如果我理解您的正确要求,则无需进行system通话。可以使用ENDFILE检查文件是否为空。

尝试一下:

awk -F"[{}]" '{print $2} ENDFILE{if(FNR==0)print "NULL"}' /home/test*/test.txt

FNR是文件中的记录数。如果文件末尾的FNR为零,则该文件没有记录,我们将打印NULL

注意:由于此解决方案使用ENDFILE,因此Ed Morton指出需要使用GNU awk(有时称为gawk)。

示例

假设我们有以下三个文件:

$ ls -1 home/test*/test.txt
home/test1/test.txt
home/test2/test.txt
home/test3/test.txt

home/test2/test.txt外,所有内容均为空,其中包含:

$ cat home/test2/test.txt
first{second}
1st{2nd}

我们的命令产生输出:

$ awk -F"[{}]" '{print $2} ENDFILE{if(FNR==0)print "NULL"}' home/test*/test.txt
NULL
second
2nd
NULL

测试不存在的文件

for d in home/test*/; do [ -f "$d/test.txt" ] || echo "Missing $d/test.txt"; done

示例输出:

$ for d in home/test*/; do [ -f "$d/test.txt" ] || echo "Missing $d/test.txt"; done
Missing home/test4//test.txt

答案 1 :(得分:0)

for dir in home/test*; do
    file="$dir/test.txt"
    if [ -s "$file" ]; then
        # exists and is non-empty
        val=$( awk -F'[{}]' '{print $2}' "$file" )

    else
        # does not exist or is empty
        val="NULL"
    fi
    printf '%s\n' "$val"
done