【问题标题】:sed substitution while reading a file happens in unexpected lines读取文件时的 sed 替换发生在意外的行中
【发布时间】:2021-03-15 06:30:31
【问题描述】:

我使用的是 macOS 11.0.1。我正在编写一个处理降价文件的 bash 脚本。它必须逐行读取文件(开头的 $HEADER 变量除外)并且:

  • 不要编辑以#开头的行
  • 为所有其他行添加前缀 ({{< p ") 和后缀 (" >}})

这是我目前得到的:

while read -r line; do
    if [[ "$line" == \#* ]]; then
        echo $line >> $OUTPUT
        continue
    else
        sed -E 's/^/{{< p "/; s/$/" >}}/' >> $OUTPUT
    fi
done < <(tail -n "+$HEADER" $INPUT)

这是我的输入(没有标题):

## I

Lorem Ipsum is simply dummy text 

我希望第一行被忽略,但这是输出:

{{< p "## I" >}}

{{< p "Lorem Ipsum is simply dummy text" >}}

奇怪的是“if”在没有 sed 的情况下也可以工作,因为我可以将匹配的行转发到另一个文件中……如果 sed 行被注释掉了。 做错了什么?

【问题讨论】:

    标签: bash macos unix sed markdown


    【解决方案1】:

    您没有向sed 提供任何输入,因此它将忽略$line,而是从标准输入读取文件的其余部分(即从tail 命令)。此外,您应该在使用 $line 等变量时将它们双引号(即 echo "$line" 而不是 echo $line)。

    但在我看来,您可以用一个 sed 命令替换整个循环:

    tail -n "+$HEADER" "$INPUT" | sed '/^#/ ! s/^.*$/{{< p & >}}/' >"$$OUTPUT"
    

    解释:/^#/ ! 前缀告诉sed 仅将其应用于以“#”开头的行。然后s/^.*$/{{&lt; p &amp; &gt;}}/ 命令将整行替换为“{{&,它告诉sed 插入整个匹配项(原始行),然后是“>}}”。

    【讨论】:

    • 谢谢! tail 命令是完美的,但我想保留循环,因为我可以在 if 语句中添加更多字符/正则表达式来避免。有没有办法对 sed 执行多项检查(例如,第一个字符是“#”还是“-”)?
    • 我自己回答:我可以将它们插入方括号,例如:sed '/^[#-]/ ! s/^.*$/{{&lt; p &amp; &gt;}}/' &gt;"$OUTPUT"
    猜你喜欢
    • 2013-09-14
    • 2011-09-06
    • 1970-01-01
    • 2020-11-19
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    相关资源
    最近更新 更多