【问题标题】:SED replacing with 'possible' newlineSED 替换为“可能的”换行符
【发布时间】:2024-08-03 15:15:01
【问题描述】:

我有一个运行良好的 sed 命令,除非它在文件的某处遇到换行符。这是我的命令:

sed -i 's,<a href="\(.*\)">\(.*\)</a>,\2 - \1,g'

现在,它运行良好,但我刚刚遇到了这个带有a 标签的文件,如下所示:

<a href="link">Click
        here now</a>

当然没有找到这个。所以我需要以某种方式修改它以允许在搜索中换行。但是我不知道如何让它允许这样做,除非我先检查整个文件并事先删除所有\n。问题是我丢失了文件中的所有格式。

【问题讨论】:

    标签: linux sed


    【解决方案1】:

    您可以通过在 sed 脚本中插入一个循环来做到这一点:

    sed -e '/<a href/{;:next;/<\/a>/!{N;b next;};s,<a href="\(.*\)">\(.*\)</a>,\2 - \1,g;}' yourfile
    

    按原样,这将在输出中留下一个嵌入的换行符,不清楚你是否想要这样。如果没有,只需替换换行符:

    sed -e '/<a href/{;:next;/<\/a>/!{N;b next;};s/\n//g;s,<a href="\(.*\)">\(.*\)</a>,\2 - \1,g;}' yourfile
    

    也许清理多余的空间:

    sed -e '/<a href/{;:next;/<\/a>/!{N;b next;};s/\n//g;s/\s\{2,\}/ /g;s,<a href="\(.*\)">\(.*\)</a>,\2 - \1,g;}' yourfile
    

    解释:/&lt;a href/{...} 让我们忽略我们不关心的行。一旦我们找到我们喜欢的,我们检查它是否有结束标记。如果没有(/&lt;\a&gt;/!),我们抓取下一行和一个换行符(N)和分支(b)回到 :next 看看我们是否已经找到它。一旦我们找到它,我们就会继续替换。

    【讨论】:

    • 我不断收到以下错误:sh: 1: Syntax error: Unterminated quoted string
    • 这来自你的外壳。确保在正确的位置有封闭的单引号。 (我将最后一个示例复制并粘贴回我的 shell,它工作正常。)顺便说一句,如果您的 sed 版本不喜欢 \s (空白)转义,您可以使用文字空格,或者 [[:space: ]] 在它的位置。
    • 明白了!我想我应该在我的 mailcap 文件中提到我在 Mutt 中使用这个命令,因此我不得不转义每个 ; :) woops。不过现在工作。
    【解决方案2】:

    这是一个快速而肮脏的解决方案,假设链接中不会有超过一个换行符:

    sed -i '' -e '/<a href=.*>/{/<\/a>/!{N;s|\n||;};}' -e 's,<a href="\(.*\)">\(.*\)</a>,\2 - \1,g'
    

    第一个命令 (/&lt;a href=.*&gt;/{/&lt;\/a&gt;/!{N;s|\n||;};}) 检查是否存在 &lt;a href=...&gt; 而没有 &lt;/a&gt;,在这种情况下,它将下一行读入模式空间并删除换行符。第二个是你的。

    【讨论】:

      最近更新 更多