【问题标题】: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”。

【问题讨论】:

    标签: string sed replace


    【解决方案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,则忽略该集合。

    【讨论】:

    • 非常感谢,不幸的是,这个对我不起作用。
    猜你喜欢
    • 2016-12-17
    • 1970-01-01
    • 2021-03-15
    • 2021-04-15
    • 2018-02-24
    • 2021-09-30
    • 2013-01-20
    • 2012-07-03
    • 1970-01-01
    相关资源
    最近更新 更多