【问题标题】:bash shell to add a new line in a file after a pattern match found [duplicate]bash shell在找到模式匹配后在文件中添加新行[重复]
【发布时间】:2014-04-04 16:11:33
【问题描述】:

我有一个文件“.gitignore”包含各种源文件名

src/abc
src/line
src/another

我喜欢在找到匹配项“src/line”后添加另一行“src/line.cpp” 结果看起来像

src/abc
src/line
src/line.cpp
src/another

我正在使用 sed 作为

set -- "$File"   // $File contains src/line
IFS="/"; declare -a Array=($*)
echo "${Array[0]}"   // This prints src
echo "${Array[1]}"   // This prints line

sed -i '/$Array[0]\/$Array[1]/a $Array[0]\/$Array[1].cpp'  $File

sed 命令不起作用。 我有一种感觉,斜线没有正确处理。如果我硬编码为

sed -i '/src\/line/a src\/line.cpp' $File

然后就可以了。 有什么解决办法吗?提前致谢!

【问题讨论】:

  • @fedorqui:这不是那个的复制品; OP 的工作线与您建议的副本相匹配。相反,OP 的问题是使用单引号 ' 而不是双引号 "

标签: bash sed


【解决方案1】:

使用 GNU sed,您可以这样做:

sed -i.BAK 's_src/line_\0\n\0.txt_'

因为它允许使用斜杠以外的其他分隔符。

【讨论】:

  • 感谢您的快速回复,它有效,但在我使用变量时无效。 sed -i.BAK 's_$Array[0]/$Array[1]_\0\n\0.cpp_' .gitignore
  • 为此,您必须使用" 作为引号字符。
【解决方案2】:

您在echo "${Array[1]}" 中正确使用了双引号,并且数组索引需要大括号{}。但是您在sed 行中忽略了这样做。所以试试:

sed -i "/${Array[0]}\/${Array[1]} *$/a ${Array[0]}\/${Array[1]}.cpp" .gitignore

我在此处为行尾添加了一个额外的$,所以:

  • 重复该命令会使文件保持不变
  • 降低无意匹配的风险

space-star-dollar *$ 处理行末尾有空格的情况。您可能还想添加一个^ 来匹配行首。

另外,您的sed 命令在$File 上运行;我想你想要.gitignore

但与其摆弄IFS 和数组,不如使用bash 的参数替换更简洁。将${Array[0]}${Array[1]} 替换为:

  ${File%/*}
  ${File#*/}

最后,您甚至不需要这样做,如果您将 sed 斜杠 / 替换为例如 @(但下划线 _ 会很糟糕,因为它通常用于文件名)。

所以倒数第二个命令行是:

sed -i "\@$File@a $File.cpp" .gitignore

或者,处理行尾的空格并避免虚假匹配:

sed -i "\@$File *\$@a $File.cpp" .gitignore

请注意,只有第一个 @ 被转义。

【讨论】:

  • 谢谢!!这些工作正常!
【解决方案3】:

你可以这样使用它:

s='src/line'; r='src/line.cpp'; sed "s~$s~&\n$r~" file
src/abc
src/line
src/line.cpp
src/another

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-25
    • 2018-09-21
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    相关资源
    最近更新 更多