2

我想打印仅修改了一些特定列的输入列 ASCII 数据文件。如果我使用 awk 修改列(例如:$NF=99),当我最终给出“print $0”命令时,它会正确打印输出,但其他列的所有空格填充、格式等都消失了。(它们基本上都被 OFS 取代了)。

有没有办法让 awk 打印完全相同的输入,只在指定的列中进行更改?我需要将此输出提供给另一个具有非常严格的读取格式的 fortran 代码。所以我不能改变行的格式。

如果 awk 不是我应该用于此目的的软件,您有什么建议?


更新:示例:

连续输入条目。

0 0 0 0 0 0 0  1936 24170  2536  1987 24094  2543  2037 24153  2550  2088 24202  2557 27 24 24.5 10000.0    0.31     0.0 10000.0     0.0     0.0     0.0    0.65

我想将该条目转换为

0 0 0 0 0 0 0  1936 24170  2536  1987 24094  2543  2037 24153  2550  2088 24202  2557 27 24 24.5 10000.0 10000.0 10000.0 10000.0 10000.0 10000.0 10000.0 10000.0

重要的部分是保持其他列的间距和位置不变。


我可以做的最接近的事情是完成我的任务是以下命令。

gawk '{output=$0;for (i=0;i<8;i++){output=substr(output,0,97+8*i-1)"10000.0"substr(output, 97+8*(i+1)-1)}; print output}'
4

3 回答 3

2

如果字段是固定宽度的,您是否考虑过不按字段编号而是按列编号进行更改?您可以通过 substr() 在 awk 中执行此操作,也可以使用 cut。

例如假设你想要的字段总是在第 56-60 列,你可以打印 substr($0,1,55) "text!" substr($0,61);

于 2013-09-18T20:09:42.207 回答
1

使用 GNU awk,以下是如何用单词“replacement”替换第三个字段:

$ cat file
field1      field2           field3    field4

$ gawk -v field=3 -v text="replacement" '{ print gensub("(^[[:space:]]*([^[:space:]]+[[:space:]]+){" field-1 "})[^[:space:]]+", "\\1" text, "") }' file
field1      field2           replacement    field4

在其他 awk 中,您可以使用 sub()s 或 match()+substr()s 做同样的事情。

为了保持字段结束位置,假设替换文本小于或等于原始文本的长度加上它前面的空格:

$ cat file
field1      field2           field3    field4
  field1      field2           field3    field4

$ awk -v fieldNr=3 -v text="replacement" -f tst.awk file
field1      field2      replacement    field4
  field1      field2      replacement    field4

$ cat tst.awk
BEGIN {
    preFld="^([[:space:]]*[^[:space:]]+){" fieldNr-1 "}"
}
{
    match($0,preFld)
    head = substr($0,RSTART,RLENGTH)

    match($0,preFld "[[:space:]]*[^[:space:]]+")
    field = substr($0,RSTART+length(head),RLENGTH-length(head))

    printf("%s% *s%s\n", head, length(field), text, substr($0,RSTART+RLENGTH))
}

有关该主题和不同解决方案的更多信息,请尝试使用 GNU gawk“patsplit()”函数和/或 FIELDWIDTHS 变量。

于 2013-03-20T03:35:55.087 回答
1

你对你在做什么不太具体,所以我不能在这里具体。那说:

听起来您需要做的是$0直接修改代码而不是选择一个字段。sub()或者gsub()可能对您有用,或者您可以使用match().

于 2013-03-19T22:30:54.200 回答