【问题标题】:Using printf in awk在 awk 中使用 printf
【发布时间】:2021-04-08 23:43:33
【问题描述】:

我有两个文件 $A 和 $B

number1 = 460
number2 = 12
number3 > 5
number4 > 20
number5 != 39
number6 != 0

$B 包含

number1 453
number2 12
number3 7
number4 19
number5 39
number6 4

我有一个 awk 命令,它比较两个文件并告诉我数字是否不匹配

output=`awk '
   {
       getline buf <f2;
       split( buf, a, " " );

       if( $1 == a[1]  && $2 == ">" && $3+0 > a[2]+0 )
           printf( "%s\n", buf );
       else if( $1 == a[1]  && $2 == "!=" && $3+0 == a[2]+0 )
           printf( "%s\n", buf );
       else if( $1 == a[1]  && $2 == "=" && $3+0 != a[2]+0 )
           printf( "%s\n", buf );

   }
' f2="$B" $A`

echo "$output"
number1 453
number4 19
number5 39

我正在尝试得到这个输出:

echo "$output"
This is the line that failed: number1 = 460 #coming from $A
This is the correct number: number1 453 #coming from $B

This is the line that failed: number4 > 20 #coming from $A
This is the correct number: number4 19 #coming from $B

This is the line that failed: number5 != 39 #coming from $A
This is the correct number: number5 39 #coming from $B

【问题讨论】:

  • awk 是一种独立的编程语言,不是 bash 的一部分。 bash 有一个 printf,但它与 awk 的 printf 完全分开。可以做很多事情来使这一点更清楚。
  • @CharlesDuffy 谢谢我会编辑标题
  • 顺便说一句,echo $output 本身就是有缺陷的(特别注意它会吃掉你的换行符并在同一行打印所有输出,即使你已经将代码固定到了awk 正在编写两行单独的输出); 总是改为echo "$output" -- 请参阅I just assigned a variable, but echo $variable prints something different!
  • @CharlesDuffy 同意了。我修好了
  • 最后一行“请注意,运算符可能会更改为 > 或 > 或&lt; 等,而不是=。但是您的输入和输出不包括这些情况。如果$Anumber1 &gt; 100$Bnumber1 &gt; 150 怎么办?输出会是什么?或者$B 只有=?如果是这样,您需要提及。

标签: bash awk printf


【解决方案1】:
$ cat tst.awk
NR==FNR {
    map[$1] = $2+0
    next
}
$1 in map {
    succ = 0
    if (    ( ($2 == "=" ) && (map[$1] == $3) ) \
         || ( ($2 == "!=") && (map[$1] != $3) ) \
         || ( ($2 == ">" ) && (map[$1] >  $3) ) \
         || ( ($2 == ">=") && (map[$1] >= $3) ) \
         || ( ($2 == "<" ) && (map[$1] <  $3) ) \
         || ( ($2 == "<=") && (map[$1] <= $3) ) \
       ) {
        succ = 1
    }
    if ( !succ ) {
        printf "This is the line that failed: %s #coming from %s\n", $0, FILENAME
        printf "This is the correct number: %s %s #coming from %s\n", $1, map[$1], ARGV[1]
        print ""
    }
}

$ awk -f tst.awk B A
This is the line that failed: number1 = 460 #coming from A
This is the correct number: number1 453 #coming from B

This is the line that failed: number4 > 20 #coming from A
This is the correct number: number4 19 #coming from B

This is the line that failed: number5 != 39 #coming from A
This is the correct number: number5 39 #coming from B

【讨论】:

  • 这很好用。我能够将它放入我的 bash 脚本中。感谢您的帮助
  • 而不是 $2 == "=" 我怎样才能调用 2 个逗号而不是 $2 列之间的任何内容
  • 抱歉,我不知道这意味着什么(我可以想象它可能意味着几件事)和 chameleon questions 无论如何都强烈劝阻,所以请询问新的后续问题。
【解决方案2】:

由于我更喜欢​​使用sed 而不是awk,所以有些东西:

diff -y file1 file2 |
    sed 's/^\(.*\) = *\([0-9]\+\)[ \o11]\+|[ \o11]\+\1/\1 :: \2 !/p;d'
number1 :: 460 ! = 453

你可以安排:

diff -y file? |
    sed 's/^\(.*\) = *\([0-9]\+\)[ \o11]\+|[ \o11]\+\1 = *\([0-9]\+\)/This is the line that failed: \1 = \2 # coming from file1\nThis is the correct number: \1 = \3 # comming from file2/p;d'
This is the line that failed: number1 = 460 # coming from file1
This is the correct number: number1 = 453 # comming from file2

【讨论】:

  • 感谢您的 sed 选项,但在我的情况下,我将有不同的运算符。文件 1 可能有 != 而文件 2 可能有 >。您可以在 awk 命令中查看条件
猜你喜欢
  • 2016-04-05
  • 1970-01-01
  • 2010-12-03
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多