使用反向引用的多行sed

时间:2010-05-10 23:02:38

标签: regex sed

我正在使用命令行脚本转换补丁脚本 - 在这些脚本中有两行组合如下:

--- /dev/null
+++ filename.txt

需要转换为:

--- filename.txt
+++ filename.txt

最初我尝试过:

less file.diff | sed -e "s/---\/dev\null\n+++ \(.*\)/--- \1\n+++ \1/"

但我不得不发现sed中的多行处理要复杂得多:(

感谢任何帮助...

3 个答案:

答案 0 :(得分:2)

您也可以先将整个文件放入保留缓冲区,然后将保留缓冲区复制到模式缓冲区,并将regexp应用于整个文件(将换行符与\ n匹配)。

看起来像这样:

sed -n '1h;1!H;${;g;s/a/b/g;p;}'

一些解释:

  • 1h - 如果第一行复制第一次复制到 保持缓冲区
  • 1!H - 如果不是第一行追加(H)到保持缓冲区
  • $ {...} - 如果最后一行
  • ;克; S / A / B / G; P; - g 复制保持模式缓冲区, s / a / b / g 执行正则表达式匹配(在这种情况下将'a'替换为'b'), p 打印结果

答案 1 :(得分:1)

谢谢 - 实际上这就是我想出来的:

sed -e "N; s/.*null\n+++ \(.*\)/--- \1\n+++ \1/" filename.txt

基本上(如果我做对了)开头的N只是告诉sed合并两行并使用两行而不是一行进行比较 - 其他一切都只是纯正则表达式...

答案 2 :(得分:-1)

您可以跳过sed并将子shell中的几个命令串起来:

(read; read x FILE; echo "--- $FILE"; echo "+++ $FILE"; cat) < file.diff

这将丢弃第一行,从第二行读取文件名,打印前两行,然后使用cat显示文件的其余部分不变。

您可以采用相同的想法并使用awk脚本执行此操作:

awk 'NR==2 {print "---", $2; print "+++", $2} NR>2 {print}' file.diff

我想两者的共同点是,自己简单地打印第一行而不是尝试返回并对其执行搜索/替换更容易。