使awk保持输入的格式间距不变输出

时间:2013-03-19 22:21:24

标签: awk

我想打印输入列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}'

3 个答案:

答案 0 :(得分:2)

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

e.g。假设您想要的字段始终位于第56-60列,您可以这样做   print substr($ 0,1,55)“text!” SUBSTR($ 0.61);

答案 1 :(得分:1)

你对你正在做的事情并不太具体,所以我不能在这里具体说明。那说:

您需要做的是让代码直接修改$0而不是选择字段。 sub()gsub()可能对您有用,或者您可以使用match()“找到”字段。

答案 2 :(得分:1)

使用GNU awk,这里是如何用“替换”一词替换第3个字段:

$ 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

在其他awks中,你可以用sub()s或match()+ substr()来做同样的事情。

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

$ 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变量。