Awk 循环遍历文件以计算字段号

Awk 循环遍历文件以计算字段号,awk,Awk,我有一个脚本bash,用于从.txt文件添加用户。 其实很简单: name firstname uid gid 空间分隔值 我想与awk确认每行是否包含4个字段。如果是,我想返回1,如果不是,则返回0 file=/my/file.txt awk=$(awk -F' ' '{(NF != 4) ? res = 0 : res = 1; print res)}' $file) echo $awk 现在,awk为每一行返回1,但我希望它在末尾返回1或0,而不是为文件中的每一行返回1或0。您可以使用

我有一个脚本bash,用于从.txt文件添加用户。 其实很简单:

name firstname uid gid
空间分隔值

我想与awk确认每行是否包含4个字段。如果是,我想返回1,如果不是,则返回0

file=/my/file.txt
awk=$(awk -F' ' '{(NF != 4) ? res = 0 : res = 1; print res)}' $file)
echo $awk
现在,awk为每一行返回1,但我希望它在末尾返回1或0,而不是为文件中的每一行返回1或0。

您可以使用:

awk 'res = NF!=4{exit} END{exit !res}' file

如果所有行都有4列,这将以
1
退出,否则它将以
0
存在。在UNIX上,如果成功,您将返回
0
=如果出现错误,则为0。对我来说,当所有记录都有
4
字段时,返回
0
更有意义;当并非所有记录都有4个字段时,返回
1
更有意义

要实现这一目标,请使用:

仅供参考:
awk
默认情况下将以
0
退出

如果要在shell条件中使用它:

#!/bin/bash
if ! awk 'NF!=4{exit 1}' file ; then
    echo "file is invalid"
fi


PS:
-F'
在您的示例中是多余的,因为
'
是最重要的。

对脚本进行细微的更改就可以了

result=$(awk -F' ' 'BEGIN{flag=1}NF!=4{flag=0;exit}END{print flag}' "$file")
[ ${result:-0} -eq 0 ] && echo "Problematic entries found in file"
方法

  • 将标志设置为1,希望每个记录包含4个字段
  • 检查记录是否实际包含4个字段,若未将标志设置为零,则退出
  • exit
    将跳过其余的输入并转到
    END
    规则
  • 打印标志并将其存储在结果中
  • 检查结果并继续执行行动课程

您不需要
END
块和
res
变量。只要
NF=4{exit 1}
起作用。只有在已经存在
END
块的情况下,才需要
res
变量机制。这是因为
exit
仍将运行
END
块。
NF=4{exit 1}
执行反向操作,对于好的情况返回
0
,对于坏的情况返回
1
。也许我误解了这个问题。但是如果是这样的话,那么OP可能误解了shell脚本中
1
0
的真实性。对我来说,如果所有记录都有
4
字段,那么返回
1
是没有意义的。是的,现在看到了。让我们看看OP是否真的想要:)@hek2mgl&anybhava OP使用了模糊/无意义的单词
return
,把你们两个都扔了出去。awk脚本不会返回任何内容,它会打印一些内容,并以状态退出。因此,当OP说
return 1
时,他希望脚本打印
1
还是以
1
状态退出?打印时,1通常表示成功,0表示失败,但退出时,0表示成功,1表示失败。根据OPs代码,他没有使用退出状态,但他应该是谁,然后hek2mgl建议的是正确的-
awk'NF=4{exit 1}'
确实是一种优越的方法!圣人说:“完美是达到的,不是当没有更多的东西可以添加时,而是当没有什么东西可以带走时。”-Exupery@karakfa谢谢!:)幸运的是,awk惊人的设计让我们能够写出这样的东西。感谢@EdMorton在讨论中添加了这些细节!当然,你是对的。请不要容忍我不把它添加到我的答案中,因为这是一种专家知识。但我会提醒自己(希望如此!)。啊,nvm!我改变了我的答案。。。再次感谢!
result=$(awk -F' ' 'BEGIN{flag=1}NF!=4{flag=0;exit}END{print flag}' "$file")
[ ${result:-0} -eq 0 ] && echo "Problematic entries found in file"