【问题标题】:Awk conditional inside bash while loopbash while 循环中的 awk 条件
【发布时间】:2018-03-20 23:30:44
【问题描述】:

我正在尝试创建一个 while 循环,逐行遍历文本文件,使用 Awk 测试字段是否为空白,然后根据该条件是真还是假执行操作。

输入文件是这样的:

$ cat testarr.csv
cilantro,lamb,oranges
basil,,pears
sage,chicken,apples
oregano,,bananas
tumeric,turkey,plums
pepper,,guavas
allspice,goose,mangos

我的预期输出是:

this_is_one_iteration
ItIsNotBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsNotBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsNotBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsNotBlank

基于Using 'if' within a 'while' loop in Bash 和类似的线程,我这样做了:

#!/bin/bash

error=ItIsBlank
success=ItIsNotBlank
while read LINE; do
echo this_is_one_iteration
QZ1=$(awk -F "," '{print (!$2)}')
if [[ $QZ1==0 ]] ; then
    echo $error
else
    echo $success
fi
done < testarr.csv

这给了我:

$ bash testloop.sh
this_is_one_iteration
ItIsBlank

所以它甚至似乎都没有遍历文件。但是,如果我取出条件,它会很好地迭代。

#!/bin/bash

error=ItIsBlank
success=ItIsNotBlank
while read LINE; do
echo this_is_one_iteration
done < testarr.csv

给予:

$ bash testloop.sh
this_is_one_iteration
this_is_one_iteration
this_is_one_iteration
this_is_one_iteration
this_is_one_iteration
this_is_one_iteration
this_is_one_iteration

此外,不使用 awk 时,条件似乎可以正常工作:

QZ1=test
while read LINE; do
echo this_is_one_iteration
if [[ $QZ1=="test" ]] ; then
    echo It_worked
fi
done < testarr.csv

给我:

$ bash testloop.sh
this_is_one_iteration
It_worked
this_is_one_iteration
It_worked
this_is_one_iteration
It_worked
this_is_one_iteration
It_worked
this_is_one_iteration
It_worked
this_is_one_iteration
It_worked
this_is_one_iteration
It_worked

【问题讨论】:

  • 所以您想在bash 脚本或Awk 命令中执行此操作?
  • 我不在乎。我只需要测试一个字段是否为空白,然后根据它做 bash 的东西。为什么将 awk 的输出传递给 bash 不起作用?
  • proper 行有 3 个字段,不正确的字段少于 3 个?
  • 不一定,尽管在这个特定的例子中,这恰好是真的。所以不,简单地测试行中的字段数量对我没有帮助。

标签: bash if-statement awk while-loop conditional


【解决方案1】:

您的脚本是正确的,除了一个小错误。添加 echo $LINE 并将其通过管道传递到 awk 语句。脚本中的 awk 没有可处理的输入。

#!/bin/bash 

error=ItIsBlank
success=ItIsNotBlank
while read LINE; do
echo this_is_one_iteration
QZ1=$(echo $LINE|awk -F "," '{print (!$2)}')
if [[ $QZ1 -eq 0 ]] ; then
 echo $error
else
 echo $success 
fi
done < testarr.csv

当我现在运行脚本时:

[ec2-user@ip check]$ ./script.sh
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration 
ItIsBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsBlank

希望这能解决您的问题。

【讨论】:

  • 谢谢,这几乎可以工作,但是 == 运算符在这种情况下不起作用,相反我使用了 -eq 并给出了预期的输出
  • 很高兴它起作用了。如果问题得到解决,请关闭线程。我已经编辑了答案,以防其他人遇到同样的问题
  • 问题不在于==-eq,而是您需要在运算符周围留出空格。 ==(或=)测试字符串相等,-eq 测试数字相等。在这种情况下,任何一个都可以。
【解决方案2】:

使用 Awk 测试字段是否为空

我想,这可以通过单个 awk 进程来实现:

awk -F, '{ print "this_is_one_iteration"; f="Not"; 
           for(i=1;i<=NF;i++) if($i=="") { f="";break }; printf "ItIs%sBlank\n",f }' testarr.csv

输出:

this_is_one_iteration
ItIsNotBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsNotBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsNotBlank
this_is_one_iteration
ItIsBlank
this_is_one_iteration
ItIsNotBlank

【讨论】:

  • 但这会让真值测试的结果执行bash代码吗?我的意思不是打印“ItIsBlank”,我只是在附和它作为将它发送到 bash 的能力的测试。
猜你喜欢
  • 2019-11-22
  • 2022-11-12
  • 2018-01-21
  • 1970-01-01
  • 2013-03-10
  • 2012-01-03
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多