如何将存储的值作为列号参数传递以在 awk 中进行编辑?

Posted

技术标签:

【中文标题】如何将存储的值作为列号参数传递以在 awk 中进行编辑?【英文标题】:How do I pass a stored value as the column number parameter to edit in awk? 【发布时间】:2016-07-05 16:41:17 【问题描述】:

我有一个带有| 分隔符的 .dat 文件,我想更改由作为参数传递并存储在 var 中的数字定义的列的值。我的代码是

awk -v var="$value" -F'|' ' FS = OFS = "|"  $1=="$id" $"\$var"=81'   
myfile.dat > tmp && mv tmp myfiletemp.dat

这会将整行更改为 8,显然不起作用。我想知道写这部分的正确方法是什么

$"\$var"=81

例如,如果我想将第四列更改为 8,并且我有value=4,我如何获得$4=8

【问题讨论】:

更改第一列(1作为变量传入):echo foo bar baz | awk '$v=k1' k=qux v=1 v 从存储的变量 v="$var" 中获取一个值,当我使用此方法时,整行变为 1 无论您一直在使用什么来尝试学习 awk,都将其扔掉,并获得 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书,因为您目前对 awk 语法和语义感到非常困惑。 我看东西,我没有研究任何关于 awk 的书,请原谅我。我找到了解决方案 【参考方案1】:

另一个答案大部分是正确的,但只是想添加一些注释,以防不完全清楚。

    引用前面带有$ 的变量会将其转换为对列的引用。所以i=3; print $i; print i 将打印第三列,然后是数字 3。 将所有变量放在命令行中可以避免尝试在单引号 awk 代码中包含 bash 变量时出现任何问题,但这是行不通的。 您可以让awk 输出到特定文件,而不是依赖 bash 来重定向输出和移动文件。 命令行中的-F 选项为您指定FS,因此无需在您的代码中重新声明它。

我会这样做:

#!/bin/bash
column=4
value=8
id=1
awk -v col="$column" -v val="$value" -v id="$id" -F"|" '
    BEGIN OFS="|"
    $1==id && $col=val; print > "myfiletemp.dat"
' myfile.dat

【讨论】:

请注意这不是惯用的awk。除非您有充分的理由(文件名取决于字段、拆分文件等),否则您不会在脚本中打印到文件名。 awk 鼓励条件action 块,应该写成... $1==id$col=val1'. There is no point of setting OFS at each loop, either set with -v OFS` 或BEGIN 块。 @karakfa 谢谢我的意思是让第一个代码块成为BEGIN(这就是为什么它是一个单独的块!)【参考方案2】:

您可以通过名称直接引用 awk 变量,稍微重写脚本并正确引用列号 var...

awk -F'|' -v var="$value" 'BEGINOFS=FS $1=="$id"$var=81'

只要 $value 是一个数字就应该可以工作。如果id 是另一个 bash 变量,则以与 awk 变量相同的方式传递它

awk -F'|' -v var="$value" -v id="$id" 'BEGINOFS=FS $1==id$var=81'

【讨论】:

Bash 变量 $id 不会在单引号内得到解释。 OP $id 中的 似乎不是一个变量。我以为这是文字。 你就是这样做的,是的。在看到您的回复之前我已经尝试过了,并且成功了,就是这样,谢谢。【参考方案3】:

不仅可以通过在变量前面加上$ 来在变量中使用数字,还可以在表达式前面加上$

$ date | tee /dev/stderr | awk 'print $(2+2)'
Mon Aug  3 12:47:39 CDT 2020
12:47:39

【讨论】:

以上是关于如何将存储的值作为列号参数传递以在 awk 中进行编辑?的主要内容,如果未能解决你的问题,请参考以下文章

如何将文件名作为 C++ 编译参数传递以在介子构建中使用?

如何将awk中一个变量的值传递给shell中的变量

在Spring boot中,如何将表单动作中的jsp表单输入的值作为参数传递

如何将不同的值传递给管道参数

存储在 EDIT 菜单中显示的值并将其作为参数传递

如何将临时表作为参数传递到单独的存储过程中