awk 在找到匹配项时替换整行
Awk replace entire line when match is found
我有以下代码:
function replaceappend() {
awk -v old="^" -v new="" '
sub(old,new) { replaced=1 }
{ print }
END { if (!replaced) print new }
' "" > /tmp/tmp$$ &&
mv /tmp/tmp$$ ""
}
replaceappend "/etc/ssh/sshd_config" "Port" "Port 222"
它工作得很好,但我希望对其进行修改,以便它替换整行内容,而不仅仅是匹配的文本。
目前它会这样做:
Port 1234 -> Port 222 1234
我希望它像这样工作:
Port 1234 -> Port 222
找到我能找到的最接近的代码 here:
awk 'NR==4 {[=13=]="different"} { print }' input_file.txt
这将用新内容替换整行匹配项。我怎样才能将它实现到我现有的代码中?
同样,对要替换的内容使用正则表达式:
replaceappend port.txt "Port.*" "Port 222"
在这里,您要用 "Port 222".
替换 Port(如果它开始该行,根据您的函数定义)加上直到该行结尾的任何内容
编辑:要使这部分功能成为函数的一部分而不是在调用中需要它,请将其修改为
function replaceappend() {
awk -v old="^.*" -v new="" '
sub(old,new) { replaced=1 }
{ print }
END { if (!replaced) print new }
' "" > /tmp/tmp$$ &&
mv /tmp/tmp$$ ""
}
如果你想替换整行,你可以简化你的函数。为了避免传递给 awk 的变量中的元字符出现问题,我建议也使用简单的字符串搜索:
awk -vold="" -vnew="" 'index([=10=],old)==1{f=1;[=10=]=new}1;END{if(!f)print new}' ""
index
returns要搜索的字符串的字符位置,从1开始。如果字符串old
在行首,则该行更改为 new
的值。块后的 1
始终为真,因此打印每一行(这是无条件 {print}
块的常见 shorthand)。
正如 mklement0 在评论中指出的那样,您传递给 awk 的变量仍然需要进行一些解释:例如,字符串 \n
将被解释为换行符,\t
作为制表符等。但是,这个问题比使用正则表达式要小得多,在正则表达式中 .
之类的东西可以匹配任何字符。
只需更改:
sub(old,new) { replaced=1 }
至:
[=11=]~old { [=11=]=new; replaced=1 }
或:
sub(".*"old".*",new) { replaced=1 }
我有以下代码:
function replaceappend() {
awk -v old="^" -v new="" '
sub(old,new) { replaced=1 }
{ print }
END { if (!replaced) print new }
' "" > /tmp/tmp$$ &&
mv /tmp/tmp$$ ""
}
replaceappend "/etc/ssh/sshd_config" "Port" "Port 222"
它工作得很好,但我希望对其进行修改,以便它替换整行内容,而不仅仅是匹配的文本。
目前它会这样做:
Port 1234 -> Port 222 1234
我希望它像这样工作:
Port 1234 -> Port 222
找到我能找到的最接近的代码 here:
awk 'NR==4 {[=13=]="different"} { print }' input_file.txt
这将用新内容替换整行匹配项。我怎样才能将它实现到我现有的代码中?
同样,对要替换的内容使用正则表达式:
replaceappend port.txt "Port.*" "Port 222"
在这里,您要用 "Port 222".
替换 Port(如果它开始该行,根据您的函数定义)加上直到该行结尾的任何内容编辑:要使这部分功能成为函数的一部分而不是在调用中需要它,请将其修改为
function replaceappend() {
awk -v old="^.*" -v new="" '
sub(old,new) { replaced=1 }
{ print }
END { if (!replaced) print new }
' "" > /tmp/tmp$$ &&
mv /tmp/tmp$$ ""
}
如果你想替换整行,你可以简化你的函数。为了避免传递给 awk 的变量中的元字符出现问题,我建议也使用简单的字符串搜索:
awk -vold="" -vnew="" 'index([=10=],old)==1{f=1;[=10=]=new}1;END{if(!f)print new}' ""
index
returns要搜索的字符串的字符位置,从1开始。如果字符串old
在行首,则该行更改为 new
的值。块后的 1
始终为真,因此打印每一行(这是无条件 {print}
块的常见 shorthand)。
正如 mklement0 在评论中指出的那样,您传递给 awk 的变量仍然需要进行一些解释:例如,字符串 \n
将被解释为换行符,\t
作为制表符等。但是,这个问题比使用正则表达式要小得多,在正则表达式中 .
之类的东西可以匹配任何字符。
只需更改:
sub(old,new) { replaced=1 }
至:
[=11=]~old { [=11=]=new; replaced=1 }
或:
sub(".*"old".*",new) { replaced=1 }