Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 用awk替换文件中的字符串(就像sed-i那样)_Regex_Bash_Awk_Sed - Fatal编程技术网

Regex 用awk替换文件中的字符串(就像sed-i那样)

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 '

我有一个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 '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'