【问题标题】:find matching text and replace next line查找匹配的文本并替换下一行
【发布时间】:2013-09-04 17:24:28
【问题描述】:

我正在尝试在文件中查找一行并将下一行替换为特定值。我试过sed,但它似乎不喜欢\n。这还能怎么做?

文件如下所示:

<key>ConnectionString</key>
<string>anything_could_be_here</string>

我想把它改成这个

<key>ConnectionString</key>
<string>changed_value</string>

这是我尝试过的:

sed -i '' "s/<key>ConnectionString<\/key>\n<string><\/string>/<key>ConnectionString<\/key>\n<string>replaced_text<\/string>/g" /path/to/file

【问题讨论】:

    标签: linux sed


    【解决方案1】:

    一种方式: 示例文件

    $ cat file
    Cygwin
    Unix
    Linux
    Solaris
    AIX
    

    使用 sed,将模式 'Unix' 之后的下一行替换为 'hi':

    $ sed '/Unix/{n;s/.*/hi/}' file
    Cygwin
    Unix
    hi
    Solaris
    AIX
    

    针对您的具体问题:

    $ sed '/<key>ConnectionString<\/key>/{n;s/<string>.*<\/string>/<string>NEW STRING<\/string>/}' your_file
    <key>ConnectionString</key>
    <string>NEW STRING</string>
    

    【讨论】:

    • 我在运行sed '/&lt;key&gt;ConnectionString&lt;\/key&gt;/{n;s/.*/&lt;string&gt;test&lt;\/string&gt;/}' $HOME/Documents/temp.rdp时得到sed: 1: "/&lt;key&gt;ConnectionString&lt; ...": bad flag in substitute command: '}'
    • @bswinnerton 在 OS X 上遇到了同样的问题,这个提示有帮助:stackoverflow.com/a/4904510/479478。所以基本上你需要把花括号分成几块:sed -i '' -e '/&lt;key&gt;ConnectionString&lt;\/key&gt;/ {' -e 'n; s/&lt;string&gt;.*&lt;\/string&gt;/&lt;string&gt;changed&lt;\/string&gt;/' -e '}' your_file
    • sed -i '' -e '/Unix/ {' -e 'n; s/.*/hihi/' -e '}'
    • @EricChen 这太棒了......我不知道它是如何工作的(或者更好地说是为什么)......但确实如此!
    • 在 Linux 上,在没有像 mac OS "plutil" 这样的命令行实用程序的情况下,此命令对于操作 iOS 应用程序中使用的基于 XML 的属性文件(例如 Info.plist)很有用。
    【解决方案2】:

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

    sed '/<key>ConnectionString<\/key>/!b;n;c<string>changed_value</string>' file
    

    !b 否定前一个地址(正则表达式)并中断任何处理,结束 sed 命令,n 打印当前行,然后将下一行读入模式空间,c 将当前行更改为命令后面的字符串。

    【讨论】:

    • 如果有osx用户感兴趣,可以使用sed的gsed insted使其工作(用macport或brew install gnu-sed安装)
    • 你能分解一下!bnc在这里做什么吗?
    • @ffledgling, !b 否定前一个地址(正则表达式)并中断任何处理,结束 sed 命令,n 打印当前行,然后将下一行读入模式空间, c 将当前行更改为命令后面的字符串。
    • @txulu 天哪,这很有帮助。我在我的 Mac 上拔头发。
    • @potong 哇谢谢!这正是我需要的!
    【解决方案3】:

    它有效。另外有兴趣提到,如果你写,

    sed '/<key>ConnectionString<\/key>/!b;n;n;c<string>changed_value</string>' file
    

    注意两个n,它在两行之后替换,依此类推。

    【讨论】:

    • @Mausy5043 -i 不会抑制输出。那是内联替换标志。此标志允许您直接修改文件。
    • @DanielOwsley 正确,所以有效地输出到终端被抑制 ;-)
    • 那是描述使用-i的效果的一个非常糟糕的方式,因为“修改原始文件”比“抑制输出”的效果要重要得多。如果有什么东西会改变你的文件,你必须知道(一个错误的sed 命令可能会导致你丢失数据)。
    • @Mausy5043 对sed 轻描淡写,如果你使用-i 来“抑制”输出,你会毁了你的一年……可能会成为新闻。就像是在说:使用rm -rf / 而不是sleep 20 - 在返回提示之前都会暂停一段时间......但结果却截然不同。 ?
    猜你喜欢
    • 2018-09-07
    • 2019-05-27
    • 2020-07-25
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 2013-04-16
    • 2020-06-07
    • 1970-01-01
    相关资源
    最近更新 更多