awk - 在 d(elete)、a(pend) 或 c(hange) 之后,SED 不处理 {} 中的多个命令
问题描述
sed应该在匹配模式的多个命令之后处理,这些命令在{cmd1;cmd2;cmd3} 等大括号中给出。但是在下面给定的代码中,d(elite) 之后的所有命令都将被忽略。
脚本.sed
s/^\(interface GigabitEthernet0\)$/\1\/0/
/interface GigabitEthernet0\/0$/{
n # process next line = 1st line (after match) to be deleted
d # Should delete '1st line (after match) to be deleted'
n # process next line = 2nd line to be altered
s/2nd line to be altered/2ND LINE AFTER ALTERATION/
n
s/3rd line to be altered/3RD LINE AFTER ALTERATION/
}
输入.txt
interface GigabitEthernet0
1st line (after match) to be deleted
2nd line to be altered
3rd line to be altered
4th line stays unchanged
sed -i -f script.sed example.txt
预期输出:
interface GigabitEthernet0/0
2ND LINE AFTER ALTERATION
3RD LINE AFTER ALTERATION
4th line stays unchanged
有效输出:
interface GigabitEthernet0/0
2nd line to be altered
3rd line to be altered
4th line stays unchanged
如上面的输出所示,要删除的第 1 行(匹配后)已被有效删除。但是以下所有行(第 2、第 3、第 4 行)都不会被替换。
顺便说一句:像 a(pend) 或 c(hange) 这样的命令的行为方式相同;所有后续命令都将被忽略。
解决方案
sed 用于做 s/old/new,仅此而已。只需使用 awk,例如使用 GNU awk 进行就地编辑(就像您使用 GNU sed 一样)和 switch 语句:
$ cat tst.awk
/^interface GigabitEthernet0$/ { lineNr=1 }
lineNr%5 {
switch (lineNr++) {
case 1: $0 = $0 "/0"; break
case 2: next; break
case 3: sub(/2nd line/,"WHATEVER"); break
case 4: $0 = toupper($0); break
}
}
{ print }
$ cat file
interface GigabitEthernet0
1st line (after match) to be deleted
2nd line to be altered
3rd line to be altered
4th line stays unchanged
$ awk -i inplace -f tst.awk file
$ cat file
interface GigabitEthernet0/0
WHATEVER to be altered
3RD LINE TO BE ALTERED
4th line stays unchanged
并且以防万一您真的只想在匹配正则表达式后打印新行而不是修改范围内的现有行(例如在@AlexHarvey的 sed 答案中),那就是:
awk '/interface GigabitEthernet0/ {
print $0 "/0\n 2ND LINE AFTER ALTERATION\n 3RD LINE AFTER ALTERATION"
c = 4
}
!(c&&c--)' file
interface GigabitEthernet0/0
2ND LINE AFTER ALTERATION
3RD LINE AFTER ALTERATION
4th line stays unchanged
请参阅https://stackoverflow.com/a/17914105/1745001上的常见 awk 习语列表,了解其c&&c--
作用。
请注意,您不必多次指定初始正则表达式,您不必担心替换文本中可能会显示哪些字符,并且您只需给出一个数字,说明您不受影响的行数需要写相同的字符的次数。
推荐阅读
- python - Python - Django - pyexcel-xlsx - 无法将两个不同工作表中的数据导入两个模型
- c++ - C++ while 循环问题 Codecademy 参考 [已解决]
- reactjs - React - event.target.id 没有从元素获取 id
- javascript - 切换两次以打开和关闭侧边栏菜单
- jquery - 如何最好地使用基于来自服务器的 json 的 javascript 呈现 html?
- php - 强制 PHP 作曲家创建本地存储库的相对而非绝对符号链接
- html - 重用具有不同输入的 Angular 组件
- spring-boot - hystrix 仪表板不加载
- c++ - 如何使替换 ac 函数的变量名出错?
- r - R Quantreg:具有分类调查数据的奇点