如果前几行匹配,则替换一行

Posted

技术标签:

【中文标题】如果前几行匹配,则替换一行【英文标题】:Replace a line if previous lines match 【发布时间】:2021-11-18 01:10:21 【问题描述】:

我正在尝试编写一个 bash 脚本,但目前卡住了。

假设我有以下文件:

targets 
        type = pppcfg_target_internet;
        name = "internet";
        only_crypt_auth = no;
        local 
                username = "";
                passwd = "";

我想更换用户名和密码。 问题是,这部分存在多次,除了第二行。

那么我想做什么:

如果前面几行有“type = pppcfg_target_internet;”,请替换“username”和“password”。

最好,我希望它保持足够的灵活性,这样我就不必将它设置为确切的行,以防代码发生一些变化或添加一行。

所以“如果搜索到的字符串上面5-10行有“pppcfg_target_internet”,替换掉“password”和“username ”。

我很乐意得到任何帮助。也建议使用“ask”还是“sed”。

【问题讨论】:

【参考方案1】:

您可以使用 sed 在要替换的特定行之间选择文本范围,如下所示

sed '/pppcfg_target_internet/,//s/passwd.*/passwd = "newpass"/g'

这意味着,在 "pppcfg_target_internet" 和 "" 的字符串之间查找以 passwd 开头的字符串并将其替换为下一个字符串:'passwd = "newpass"'

也许创建一些独特的块结尾会很好

【讨论】:

非常感谢!如果我稍微扩展我的问题,我希望你不介意。假设我要替换的字符串在“FILE_A.txt”中,我想用“FILE_B.txt”中的字符串替换它。如果我在两个不同的文件中工作,我将如何调整您的建议? 如果 FILE_B.txt 包含单个字符串,您可以先读取它。默认情况下,读取命令会将字符串读取到 REPLY 变量:read FILE_B.txt && sed "/pppcfg_target_internet/,//s/passwd.*/passwd = \"$REPLY\"/g"【参考方案2】:

这可能对你有用(GNU sed):

sed -E '/^[^\n]*pppcfg_target_internet/:a;N;/passwd/!ba
        s/^([^\n]*\n)5,10[^\n]*$/&/;Tb
        s/(username = ).*/\1"new user";/m
        s/(passwd = ).*/\1"new pass";/m;:b;P;D' file

收集type = pppcfg_target_internet;passwd 之间的行,然后替换新的用户和密码值。

注意在替换命令上使用m 标志来确保替换只发生在匹配的行上。另请注意,如果收集的行数小于 5 或​​大于 10,则忽略该集合。

【讨论】:

非常感谢,不幸的是,这个对我不起作用。

以上是关于如果前几行匹配,则替换一行的主要内容,如果未能解决你的问题,请参考以下文章

ansible的lineinfile模块

如果不匹配则替换字符

如果匹配条件,则将值替换为上一行

mysql 查询第几行到第几行记录 查询最后一行和第一行记录 查询前几行和后几行记录(查询正序或者倒序前几行)

mysql怎样删除前几行数据

如果匹配列表中的项目,则替换字符串中的项目