我有一个带有16个字段的制表符分隔文件。我可以使用awk
有条件地改变一个或多个字段并打印整行作为输出吗?例如,根据第一个字段中的值,我想说一个特定的数字添加到字段4,依此类推。但作为输出我必须打印整行。如果是的话,我想知道如何。
答案 0 :(得分:6)
是的,这是一种方法:
awk '$1 == "ALTER" { $5=$5+5 } 1'
使用etuardu的示例文件,会产生
ALTER xx yy zz 15 10
NOALT aa bb cc 20 20
ALTER 11 22 33 35 30
这是它的工作原理。有两种情况,表示为awk模式和操作。在第一个模式中,模式是对第一个字段的测试,以查看它是否等于"ALTER"
,如果模式评估为true,则调用修改第五个字段的操作。第二种模式是最终1
;它始终是真的,因此执行隐式print
动作。
使用此解决方案的一个怪癖:输入中读取的字段分隔符不必是输出中的字段分隔符。使用上面的简单形式,输入中的字段分隔符被视为空格,而单个空格被写入输出;如果不是您想要的,请将FS
和OFS
设置为特定值。但是,只有更改字段的行才会有新的字段分隔符,因此像'$ 1 = $ 1'这样的空操作将强制重建所有记录(这是更改字段分隔符的一种方便方法,仅使用{{1 }})。
答案 1 :(得分:1)
是。这是一个使用示例(可能不是最聪明的):
etuardu@subranu:~$ cat sample.txt
ALTER xx yy zz 10 10
NOALT aa bb cc 20 20
ALTER 11 22 33 30 30
etuardu@subranu:~$ awk '{ if ($1=="ALTER") print $1,$2,$3,$4,$5+1,$6-1; else print $0 }' sample.txt
ALTER xx yy zz 11 9
NOALT aa bb cc 20 20
ALTER 11 22 33 31 29
请参阅man awk
或一些在线教程(有很多内容)以获取更多信息。
答案 2 :(得分:1)
这个(来自@etuardu的文件样本) -
awk '{if($1=="ALTER") {$5=$5+1;print"\n";for (i=1;i<=NF;i++) printf $i" ";} else print "\n"$0}' input_file | sed '/^$/d'
示例:
[jaypal~/Temp]$ cat text8
NOALT aa bb cc 20 20
ALTER xx yy zz 10 10
ALTER xx yy zz 10 10
NOALT aa bb cc 20 20
ALTER 11 22 33 30 30
[jaypal~/Temp]$ awk '{if($1=="ALTER") {$5=$5+1;print"\n";for (i=1;i<=NF;i++) printf $i" ";} else print "\n"$0}' text8 | sed '/^$/d'
NOALT aa bb cc 20 20
ALTER xx yy zz 11 10
ALTER xx yy zz 11 10
NOALT aa bb cc 20 20
ALTER 11 22 33 31 30