Reputation: 131
I am trying to follow the post
How to move specified line in file to other place with regexp match (bash script)?
to my example file
asdasd0
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd2
asdasd3
asdasd4
DEFAULTS {
asdasd6
The final output should look like
asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd6
I have tried the following
sed "/-SRC_OUT_DIR.*/d;/DEFAULTS { /a"$(sed -n '/-SRC_OUT_DIR.*/p' test.txt) test.txt`
but it is not working. I get the following output
sed:can't read =: No such file or directory
sed:can't read "/a/b/c/d/e/f/g": No such file or directory
asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR
asdasd6
I am also wondering why can't I use \1
, \2
to print the line that needs to be moved. I tried that but it prints nothing. How would I write a sed
command if I need to move multiple matching lines to different places in the file?
Upvotes: 1
Views: 2783
Reputation: 52122
You could store the matching line in the hold space, delete it and then append the hold space to the line after which you want to insert:
$ sed '/^-SRC_OUT_DIR/{h;d;};/^DEFAULTS {/G' infile
asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd6
Upvotes: 4
Reputation: 26471
While you ask a sed
solution I would propose to use awk
for this.
Using an ugly nesting of a multitude of sed
commands is not really recommended. Especially because you read your file twice.
Here is an awk
awk '/SRC_OUT_DIR/{t=$0;next}1;/DEFAULTS/{print t}' file
How does it work?
awk will read your file
line by line. Per line, it will do the following three commands one after the other:
/SRC_OUT_DIR/{t=$0;next}
: if the line contains a substring matching SRC_OUT_DIR
, then store the line in a variable t
and move to the next
line (don't execute 2 and 3)1
: default action: print the line/DEFAULTS/{print t}
: if the current line contains the substring DEFAULTS
, print the line stored in variable t
If you have multiple lines to move (this only moves downwards):
awk '/pattern1/ {t[1]=$0;next}
/pattern2/ {t[2]=$0;next}
/pattern3/ {t[3]=$0;next}
/target3/ { print t[3] }
1
/target1/ { print t[1] }
/target2/ { print t[2] }' file
note that pattern3
will be printed before target3
.
Upvotes: 3