【问题标题】:awk and shell variables | using a changing variableawk 和shell 变量|使用变化的变量
【发布时间】:2021-04-01 15:05:21
【问题描述】:

假设我有一个循环(bash shell),结构如下:

for iter in `seq 1 to 5`
  do
    <bunch of stuff that generates a file called test.dat>
    awk -v var="$iter" '{print $1 " " var}' test.dat > mod_test.dat
done

我不太明白为什么 awk 没有写出 $iter 变量的当前值。

例如,test.dat 可能看起来像(比如说)

abcd
efgh
ijkl
mnop

我期待着结束

abcd 1
efgh 2
ijkl 3
mnop 4

[基本上,我只是想将循环计数器放在每一行的末尾。]

但是,我的脚本不起作用,因为输出文件 (mod_test.dat) 很简单

 abcd 5
 efgh 5
 ijkl 5
 mnop 5

换句话说,它只是将计数器的最后一个值附加到每一行。我知道计数器正在工作(循环中的 echo $iter 显示它正在递增)。

我做错了什么明显的事情?我已经尝试了所有我知道的技巧来设置 awk 变量(var=$iter, var="$iter", var="$iter"....),但没有成功。我是一个 awk 半新手,所以如果这甚至低于微不足道的水平,我们深表歉意。

非常感谢。

【问题讨论】:

  • 您能否在这里更清楚地说明您要实现的目标,因为如果您只是想打印越来越多的数字,您可以在awk 中完成。另请注意:您的 seq 命令应为 seq 1 5
  • 另外,test.dat &gt; mod_test.dat 用 awk 的最后一次迭代输出覆盖目标文件(这也可能不是您想要的)。使用&gt;&gt; 追加到目标文件。
  • 是的 - 输入 seq 代码的错误。感谢您指出。我想将计数器附加到文件每一行的末尾。我不明白为什么目前的代码只是添加了计数器的最后一个值。
  • 为什么是代码:第一次迭代:var=1 和 awk 处理文件中的每条记录并输出到目标文件。第二次迭代,var=2 和 awk 处理文件中的每条记录并输出到目标文件。等等。丢失 bash 循环并仅使用 awk '{print $0,NR}' file 是最快的解决方法。
  • 相对于Use grep to find the line in the listing containing value I need. Use awk to pull the value from that line, - 当您使用 awk 时,您永远不需要 grep。 grep 'foo' | awk '{bar}' = awk '/foo/{bar}'.

标签: bash awk


【解决方案1】:

您正在处理文件 5 次。您所看到的只是您第 5 次处理文件,之前的每次迭代都会被下一次覆盖。

awk 可以自己处理:

  • 最简单的:awk '{print $0, NR}' file

  • 或使用计数器:awk '{print $0, ++n}' file - 如果您不想计算空行数,您可能需要这样做:

    $ printf "%s\n" one two "" three "" four five | awk 'NF > 0 {$(NF+1) = ++n} 1'
    one 1
    two 2
    
    three 3
    
    four 4
    five 5
    

【讨论】:

    【解决方案2】:

    正如已经指出的那样,您在循环的每次迭代中都会覆盖 mod_test.dat,并且每次调用 awk 时都会打印 test.dat 的每一行。

    听起来你正在尝试做这样的事情:

    for iter in {1..5}; do
        <bunch of stuff that generates a file called test.dat>
        awk -v var="$iter" '/look for something/{print $1, var; exit}' test.dat
    done > mod_test.dat
    

    【讨论】:

    • 当然,但是如果不先 grepping 就无法“寻找某些东西”——这给了我一条线,然后 awk 从中提取“数据”(值)线。如果有办法在 awk 中完成这一切,请注册我。基本上,我有一个来自模拟的 300-400 行输出文件,并且需要从整个事情中提取 1 个数字——用 grep 来查找它所在的行很简单(它前面是一个唯一的字符串)。接下来发生的事情导致我使用 awk。
    • awk '/look for something/{print}' 替换 grep 'look for something' | awk '{print}'。 awk 和 grep 一样微不足道,但我们无法告诉您如何在没有看到一些示例输入的情况下执行您想做的任何事情,并且您告诉我们您想从该输入中提取什么。请更新您的问题以显示minimal reproducible example,然后我们可以准确地告诉您如何编写代码。
    • 实际上,最好只接受您对最初提出的问题的答案之一,然后询问有关如何仅使用 awk 而不是 grep + awk 的后续问题。跨度>
    猜你喜欢
    • 1970-01-01
    • 2014-01-20
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多