【问题标题】:How to call awk from bash with last field as variable如何使用最后一个字段作为变量从 bash 调用 awk
【发布时间】:2018-11-17 19:10:24
【问题描述】:

假设我有一个名为 input.csv 的 CSV 输入文件:

1,2,3,valueIWantToPrint
3,5,2,valueIWantToPrint

我目前需要使用 awk 打印该输入的每一行的最后一个元素,这可以通过字段分隔符和 NF 变量轻松完成:

awk -F"," '{print $NF}' input.csv

但是现在假设我想让我想要打印的字段成为一个变量,因为稍后输入格式可能会改变并且它将是一个不同的字段。

输入文件:

1,2,valueIWantToPrint,3
3,5,valueIWantToPrint,2

脚本:

FIELD_TO_PRINT=3
awk -F"," -v fieldToPrint=FIELD_TO_PRINT '{print $fieldToPrint}' input.csv

好的,这很容易。但现在为了使其尽可能灵活,我希望能够将 FIELD_TO_PRINT 设置为 NF 的等价物,这样我就可以打印最后一个值,而不管字段数如何。我所追求的是这样的:

输入:

1,2,3,7,2,5,23,1,3,6,valueIWantToPrint
3,5,2,6,3,valueIWantToPrint

此脚本不起作用,但说明了我要完成的工作:

FIELD_TO_PRINT=NF
awk -F"," -v fieldToPrint=FIELD_TO_PRINT '{print $fieldToPrint}' input.csv

有没有一种方便的方法可以将变量设置为“记录中的最后一个字段”?这个例子很简单,但最终 FIELD_TO_PRINT 变量将放在一个单独的配置文件中,并且 awk 脚本会更大更复杂。所以有一个好的方法来完成这将是非常有用的。

【问题讨论】:

  • 是否所有行的列数都相同?您正在使用的另一个文件可以运行命令吗?即FIELD_TO_PRINT 可以是命令的输出吗?
  • 我迷路了——awk -F, '{print $NF}' file 正是这样做的——打印“记录中的最后一个字段”,因此它将在您的最后一个示例中输出valueIWantToPrint。你想要一些不同的东西吗?
  • @DavidC.Rankin: OP 说我想列号是动态的,所以如果通过 NF 作为变量值,它就不起作用
  • 这就是我摸不着头脑的原因,NF 是每行 (record) 的字段数——它不是整个文件的固定值。它将正确处理上一个示例中的两行。
  • @DavidC.Rankin:我的意思是$ awk -F"," -v fieldToPrint="NF" '{print $fieldToPrint}' file 不会按预期工作,但$ awk -F"," '{print $NF}' file

标签: bash csv awk field


【解决方案1】:

你可以使用这种迂回的方式:

否定的n 表示NF

n=-1
awk -F, -v n="$n" '{print (n<0 ? $NF : $n)}' f.csv

valueIWantToPrint
valueIWantToPrint

n &gt; 0打印编号字段时:

n=3
awk -F, -v n="$n" '{print (n<0 ? $NF : $n)}' f.csv

3
2

【讨论】:

  • 哦,所以他想要指定字段或最后一个字段的三元。现在这更有意义了。
  • 不能是迂回的方式,这是的方式! ++
  • 太棒了!这正是我所追求的
【解决方案2】:

你可以使用这个技巧

$ awk -F, -v n=-1 '{print (n<0)?$(NF+n+1):$n}' file

valueIWantToPrint
valueIWantToPrint

假设负索引从 NF 开始倒数,所以 -2 表示倒数第二个字段等。

【讨论】:

  • 这正是我要建议的。
猜你喜欢
  • 1970-01-01
  • 2013-07-29
  • 2022-01-05
  • 2017-02-09
  • 2018-07-31
  • 2017-06-18
  • 2015-05-17
  • 1970-01-01
相关资源
最近更新 更多