如何使用sed批量编辑指定多行?bash循环sed语法报错解决
报错原因与批量修改方案
原有循环代码的报错原因
- 语法结构缺失:bash的
for循环要求循环体必须包裹在do和done关键字之间,原代码漏写了do,直接在取值列表后拼接sed命令,直接触发语法解析错误。 - 取值列表格式错误:bash遍历离散值不需要加方括号
[],多个值直接用空格分隔即可,原代码写的[24,28,...]会被识别为单个字符串或通配符匹配项,无法按行号逐个遍历。 - 变量无法展开:sed命令外层用了单引号,bash在单引号作用域内不会解析
$X变量,会直接把$X作为字面量传给sed,sed无法识别非法行号会执行失败。 - 逻辑冗余:每次循环都调用一次sed读写文件,执行效率低,且重复运行会重复追加编译参数,导致配置文件内容异常。
推荐方案:单条sed命令一次性完成修改
sed原生支持多段操作指令用分号分隔,不需要写循环,单次执行即可完成所有指定行的修改,效率更高也不容易出错:
# 执行前先备份原文件,避免改错无法回退 cp $HOME/WRF/Downloads/NCEPlibs/macros.make.linux.gnu $HOME/WRF/Downloads/NCEPlibs/macros.make.linux.gnu.bak # 单条sed完成所有指定行修改 sed -i ' 24s/= /= -std=legacy -fallow-invalid-boz/; 28s/= /= -std=legacy -fallow-invalid-boz/; 32s/= /= -std=legacy -fallow-invalid-boz/; 36s/= /= -std=legacy -fallow-invalid-boz/; 40s/= /= -std=legacy -fallow-invalid-boz/; 45s/= /= -std=legacy -fallow-invalid-boz/; 49s/= /= -std=legacy -fallow-invalid-boz/; 53s/= /= -std=legacy -fallow-invalid-boz/; 56s/= /= -std=legacy -fallow-invalid-boz/; 60s/= /= -std=legacy -fallow-invalid-boz/; 64s/= /= -std=legacy -fallow-invalid-boz/; 68s/= /= -std=legacy -fallow-invalid-boz/; 69s/= /= -std=legacy -fallow-invalid-boz/; 73s/= /= -std=legacy -fallow-invalid-boz/; 74s/= /= -std=legacy -fallow-invalid-boz/; 79s/= /= -std=legacy -fallow-invalid-boz/ ' $HOME/WRF/Downloads/NCEPlibs/macros.make.linux.gnu
如果需要避免重复执行时重复追加参数,可以给匹配规则加判断,只有行内不存在-std=legacy时才执行替换,把对应行的规则改成如下格式即可:24!/\-std=legacy/s/= /= -std=legacy -fallow-invalid-boz/;
修正后的循环写法(仅作语法参考,不推荐使用)
如果一定要用循环逻辑实现,修正语法后的可运行代码如下:
cp $HOME/WRF/Downloads/NCEPlibs/macros.make.linux.gnu $HOME/WRF/Downloads/NCEPlibs/macros.make.linux.gnu.bak for X in 24 28 32 36 40 45 49 53 56 60 64 68 69 73 74 79 do sed -i "${X}s/= /= -std=legacy -fallow-invalid-boz/" $HOME/WRF/Downloads/NCEPlibs/macros.make.linux.gnu done
注意:替换规则不需要加
g全局替换标志,每行仅需替换第一个等号即可,加全局标志会误替换行内后续的等号。
内容的提问来源于stack exchange,提问作者user16541602
相关产品推荐
相关产品推荐

