开发者

multiline sed using backreferences

I'm converting patch scrip开发者_Go百科ts using a commandline script - within these scripts there's the combination two lines like:

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

which needs to be converted to:

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

Initially I tried:

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

But I had to find out that multiline-handling is much more complex in sed :(

Any help is appreciated...


You can also first get the whole file into the holding buffer, then copy the holding buffer to the pattern buffer and apply your regexp on the whole file (matching newlines with \n).

Looks like this:

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

Some explanation:

  • 1h - if first line copy first copy to holding buffer
  • 1!H - if not first line append (H) to holding buffer
  • ${...} - if last line do
  • ;g;s/a/b/g;p; - g copy holding to pattern buffer, s/a/b/g do the regular expression match (in this case replace 'a' with 'b'), p print the result


thanks - actually that's what I came up with:

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

basically (if I got it right) the N at the beginning just tells sed to merge two lines and enable a comparision using two lines instead of one - everything else is just pure regex ...


You could skip sed and string together a couple of commands in a sub-shell:

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

This discards the first line, reads the file name from the second line, prints the first two lines, and then uses cat to display the rest of the file unchanged.

You could take the same idea and do it with an awk script:

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

I guess the common idea in both is that it's easier to simply print out the first line yourself rather than try to go back and perform a search/replace on it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜