Regex 用awk替换文件中的字符串(就像sed-i那样)
我有一个Openwrt无线配置文件。 格式如下:Regex 用awk替换文件中的字符串(就像sed-i那样),regex,bash,awk,sed,Regex,Bash,Awk,Sed,我有一个Openwrt无线配置文件。 格式如下: config wifi-iface 'priv' option device 'radio0' option ifname 'priv0' option mode 'ap' option encryption 'psk-mixed' option macfilter 'allow' option macfile '/tmp/mac_filter_priv' option disabled '
config wifi-iface 'priv'
option device 'radio0'
option ifname 'priv0'
option mode 'ap'
option encryption 'psk-mixed'
option macfilter 'allow'
option macfile '/tmp/mac_filter_priv'
option disabled '1'
option hidden '1
config wifi-iface 'orphan'
option device 'radio0'
我需要做的是找到wifi iface“priv”,并将选项从1更改为0。
我试着用awk这样做:
awk 'BEGIN{f=0} /wifi-iface \47priv/{f=1} {if(f==1 && $2=="disabled")
{gsub("1", "0"); f=0; print}}' wireless
看起来很好,但我不能以交互方式执行,所以文件没有更改。如果awk不支持-i选项,如何执行此操作?您可以将此awk命令与空RS记录分隔符一起使用:
awk -v RS= '/wifi-iface \047priv/{sub(/option disabled [^\n]*/,
"option disabled \047" 0 "\047"); print $0 ORS; next} 1' config
config wifi-iface 'priv'
option device 'radio0'
option ifname 'priv0'
option mode 'ap'
option encryption 'psk-mixed'
option macfilter 'allow'
option macfile '/tmp/mac_filter_priv'
option disabled '0'
option hidden '1
config wifi-iface 'orphan'
option device 'radio0'
一定是awk吗?您可以使用sed,它有一个-i选项:
在这里,前导地址对将s命令限制在带有iface“priv”的部分。使用GNU awk for-i替换并整理脚本:
$ cat tst.awk
/config wifi-iface / { f = (/\047priv\047/ ? 1 : 0) }
f && $2=="disabled" { sub(/1/,"0") }
{ print }
$ awk -i inplace -f tst.awk file
$ cat file
config wifi-iface 'priv'
option device 'radio0'
option ifname 'priv0'
option mode 'ap'
option encryption 'psk-mixed'
option macfilter 'allow'
option macfile '/tmp/mac_filter_priv'
option disabled '0'
option hidden '1
config wifi-iface 'orphan'
option device 'radio0'
对于任何其他awk,您都可以像使用任何UNIX命令一样:
awk -f tst.awk file > tmp && mv tmp file
或者,如果您对tmp文件严重过敏:
$ cat tst.awk
/config wifi-iface / { f = (/\047priv\047/ ? 1 : 0) }
f && $2=="disabled" { sub(/1/,"0") }
{ rec = rec $0 RS }
END { close(FILENAME); printf "%s", rec > FILENAME }
$ awk -f tst.awk file
$ cat file
config wifi-iface 'priv'
option device 'radio0'
option ifname 'priv0'
option mode 'ap'
option encryption 'psk-mixed'
option macfilter 'allow'
option macfile '/tmp/mac_filter_priv'
option disabled '0'
option hidden '1
config wifi-iface 'orphan'
option device 'radio0'
您可以运行多个用分号或&&分隔的命令吗?您始终可以复制文件,覆盖原始文件,然后一次性删除副本。例如:cp wireless.bak&&awk“代码在这里”wireless.bak>wireless&&rm wireless.bak谢谢,但它也删除了我希望保留的所有空行。这可以通过使用上面的awk-v RS=-v ORS='\n\n''…'实现。是的,我的错误是,我最初尝试使用FPAT,然后更改为当前解决方案。不要使用\x27,请改用\047。请尝试awk'BEGIN{print\047foo!\047}和awk'BEGIN{print\x27foo!\x27}以了解为什么还要查看。正如我所说,没有-I inplace选项。我在考虑不使用tmp文件的解决方案,但没有这样的解决方案。现在我也知道sed——我也用同样的方法——使用tmp文件。在非GNU awk中,你完全可以不用tmp文件来完成它,这是不值得的。我将编辑我的问题以显示它。Done.sed工作正常,谢谢。我决定知道强大的awk是如何实现这一功能的:sed-I/^config wifi iface'priv'/,/option disabled/s/'1'/'0'/wirelessCostas,它还将编辑禁用之前碰巧有'1'的任何选项。
$ cat tst.awk
/config wifi-iface / { f = (/\047priv\047/ ? 1 : 0) }
f && $2=="disabled" { sub(/1/,"0") }
{ rec = rec $0 RS }
END { close(FILENAME); printf "%s", rec > FILENAME }
$ awk -f tst.awk file
$ cat file
config wifi-iface 'priv'
option device 'radio0'
option ifname 'priv0'
option mode 'ap'
option encryption 'psk-mixed'
option macfilter 'allow'
option macfile '/tmp/mac_filter_priv'
option disabled '0'
option hidden '1
config wifi-iface 'orphan'
option device 'radio0'