and*_*rec 2 sed awk shell-script
我想将第一、第三、第五行等所有字段中的值 3 和 4 分别替换为 0 和 1,直到以下数据集结束:
2 4 3 0
2 4 3 0
3 0 4 4
3 0 4 4
4 2 4 3
4 2 4 3
2 3 4 2
2 3 4 2
Run Code Online (Sandbox Code Playgroud)
所以,想要的结果是:
2 1 0 0
2 4 3 0
0 0 1 1
3 0 4 4
1 2 1 0
4 2 4 3
2 0 1 2
2 3 4 2
Run Code Online (Sandbox Code Playgroud)
我正在使用以下代码来做到这一点:
awk '{for (i = 1; i <= NR; i=(i+2))
if($i == 3) {$i = 0}
if($i == 4) {$i = 1}
}
END {print $0}' b.temp
Run Code Online (Sandbox Code Playgroud)
但是,此代码的输出只是 b.temp 文件 (2 3 4 2) 最后一行中的值。
我怎样才能做到这一点?代码需要针对任意数量的行和字段。解决方案可以是 awk、sed 或 shell 脚本中的其他替代方法。
提前致谢
使用 sed:
sed 'y/34/01/;n' file
Run Code Online (Sandbox Code Playgroud)
意思是:
但是,如果数据包含,例如,14,将其转换为 11,这将失败。要解决这个问题,请选择
sed 's/\<4\>/1/g;s/\<3\>/0/g;n' file
Run Code Online (Sandbox Code Playgroud)
你的方法的问题是你只有一个print
语句,在END
块中。该$0
块中的值是文件最后一行的内容。因此,您的awk
代码只会打印文件的最后一行。
另请注意,除非在块之前有条件(例如仅适用于文件结尾),否则awk
将操作应用于每一行。所以,你的代码会尝试检查第一,第三等领域的每一行,如果它是或替换成或分别...但从来没有打印结果。{ ... }
END
3
4
0
1
为了将规则应用于每条奇数行,您可以检查是否NR%2
为 1(或只是非零):
awk 'NR%2{for (i=1;i<=NF;i++) if ($i==3 || $i==4) $i-=3}1' b.temp
Run Code Online (Sandbox Code Playgroud)
的1
,存在的一个规则的外面时,是一种awk
用于“打印从所有变换所得的线执行”的简写符号。