我想打印输入列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}'
答案 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变量。