Move few lines after a pattern match to another position (just before another match) in shell

Clash Royale CLAN TAG#URR8PPP
Giving an example to explain the problem.
I have a file with
AAA
BBB
CCC
DDD
EEE
FFF
ABAB
ACAC
GGG
HHH
I want to shift 2 lines after match ABAB to just before DDD. So, the modified file would look like:
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
Looking for some cool way to handle this preferably using sed.
text-processing sed
add a comment |
Giving an example to explain the problem.
I have a file with
AAA
BBB
CCC
DDD
EEE
FFF
ABAB
ACAC
GGG
HHH
I want to shift 2 lines after match ABAB to just before DDD. So, the modified file would look like:
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
Looking for some cool way to handle this preferably using sed.
text-processing sed
Are there really blank lines between each entry?
– steeldriver
Feb 24 at 3:32
add a comment |
Giving an example to explain the problem.
I have a file with
AAA
BBB
CCC
DDD
EEE
FFF
ABAB
ACAC
GGG
HHH
I want to shift 2 lines after match ABAB to just before DDD. So, the modified file would look like:
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
Looking for some cool way to handle this preferably using sed.
text-processing sed
Giving an example to explain the problem.
I have a file with
AAA
BBB
CCC
DDD
EEE
FFF
ABAB
ACAC
GGG
HHH
I want to shift 2 lines after match ABAB to just before DDD. So, the modified file would look like:
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
Looking for some cool way to handle this preferably using sed.
text-processing sed
text-processing sed
edited Feb 24 at 3:22
Sergiy Kolodyazhnyy
10.6k42763
10.6k42763
asked Feb 24 at 3:03
PratapPratap
184
184
Are there really blank lines between each entry?
– steeldriver
Feb 24 at 3:32
add a comment |
Are there really blank lines between each entry?
– steeldriver
Feb 24 at 3:32
Are there really blank lines between each entry?
– steeldriver
Feb 24 at 3:32
Are there really blank lines between each entry?
– steeldriver
Feb 24 at 3:32
add a comment |
4 Answers
4
active
oldest
votes
NOTE: I'm assuming your data does not have blank lines between each entry; if it does, then you will need to address four lines i.e. change + to +3
With GNU ed:
$ ed -s file <<EOF
/ABAB/,//+m?DDD?-
,p
q
EOF
where
/ABAB/,//+addresses a range of lines from/ABAB/to the previous match//plus one linemmoves the addressed lines to?DDD?-the previous line matchingDDD, minus one line,pprint the whole buffer
As a one-liner,
printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s file
To edit file in place, replace ,pnqn by ,wqn (write and quit).
Works great! How do we handle this when we have to do this processing on output of a previously processed output? sat if I want to cat file and then do this processing after that, how do I do it?
– Pratap
Feb 24 at 7:10
@Pratap yes you can - but it's not just a matter of piping the previous command output, sinceedreads its commands via standard input. Instead, you have to pass the command as a special "file", preceding it with a!character e.g.printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s !'cat file'.
– steeldriver
Feb 24 at 14:20
add a comment |
You wanted with sed so you can do it as shown:
sed -e '
/DDD/,/ABAB/! b
H;/ABAB/!$!d;;g
s/(n.*)n(.*)/21/
' input.txt
This gets straightforward with the ed editor:
ed -s input.file - <<eof
/ABAB/m?DDD?-
wq
eof
add a comment |
Python (single read)
Reading a file in one and storing what's between the two patterns can be done as so:
#!/usr/bin/env python3
import sys
flag=False
vals =
with open(sys.argv[1]) as fd:
for line in fd:
if line.strip() == "DDD" or flag:
# encountered line where we should stop appending values
if line.strip() == "ABAB":
flag = False
# print the line and two others, then move in what was between originally
print(line.strip())
for i in range(2):
print(fd.readline().strip())
print("n".join(vals))
continue
# store values while we haven't hit ABAB
flag = True
vals.append(line.strip())
continue
print(line.strip())
Python ( double read)
Re-using original awk idea I had to read the file twice, we can do the same in Python:
#!/usr/bin/env python3
import sys
flag_pos,match = 0,0
vals =
with open(sys.argv[1]) as fd:
for index, line in enumerate(fd):
if line.strip() == "DDD":
flag_pos = index
if line.strip() == "ABAB":
vals.append(line.strip())
fd.readline()
vals.append(fd.readline().strip())
with open(sys.argv[1]) as fd:
for index,line in enumerate(fd):
if index == flag_pos:
print("nn".join(vals),"n")
if line.strip() in vals:
fd.readline()
continue
print(line.strip())
This script can be saved as movelines.py and called as ./movelines.py input.txt
AWK
This is doable in gawk probably much more easily than sed:
$ awk 'NR==FNR && $0=="ABAB" a[i++]=$0;getline;getline; a[i++]=$0; ; NR!=FNR if($0=="DDD") for(val in a) printf "%snn",a[val]; if($0 == "ABAB") getline;getline;getline; print $0 ' input.txt input.txt
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
The trick here is that we pass the file to awk twice for reading, and distinguish between first reading that finds the lines we want to move and second reading where we actually move them.
If your actual file does not have blank lines as in the example you provided, you just need one getline instead of two and "%sn" in the second part of the code will suffice.
For readability, here's a multipline version of the code with comments:
# on first reading NR != FNR,
# so lets store ABAB and the other line into array
awk 'NR==FNR && $0=="ABAB"
# i variable will be initialized once incremented first time
a[i++]=$0;getline;getline; a[i++]=$0;
;
# Here we are reading the same file second time
NR!=FNR
if($0=="DDD")
for(val in a)
printf "%snn",a[val];
# Skip what we matched already
if ($0 == "ABAB")
getline;
getline;
getline;
print $0
' input.txt input.txt
add a comment |
I have done by below method
command
Step1: h=`sed -n '/[A-Za-z]4/p' filename| sed -n '1p'`
step2:m=`sed -n '/[A-Za-z]4/p' filename| sed -n '2p'`
step3
sed '/[A-Z]4/d' filename|sed "/CCC/s/.*/&nn$hnn$m/g"| sed '/^$/d'
output
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f502622%2fmove-few-lines-after-a-pattern-match-to-another-position-just-before-another-ma%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
NOTE: I'm assuming your data does not have blank lines between each entry; if it does, then you will need to address four lines i.e. change + to +3
With GNU ed:
$ ed -s file <<EOF
/ABAB/,//+m?DDD?-
,p
q
EOF
where
/ABAB/,//+addresses a range of lines from/ABAB/to the previous match//plus one linemmoves the addressed lines to?DDD?-the previous line matchingDDD, minus one line,pprint the whole buffer
As a one-liner,
printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s file
To edit file in place, replace ,pnqn by ,wqn (write and quit).
Works great! How do we handle this when we have to do this processing on output of a previously processed output? sat if I want to cat file and then do this processing after that, how do I do it?
– Pratap
Feb 24 at 7:10
@Pratap yes you can - but it's not just a matter of piping the previous command output, sinceedreads its commands via standard input. Instead, you have to pass the command as a special "file", preceding it with a!character e.g.printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s !'cat file'.
– steeldriver
Feb 24 at 14:20
add a comment |
NOTE: I'm assuming your data does not have blank lines between each entry; if it does, then you will need to address four lines i.e. change + to +3
With GNU ed:
$ ed -s file <<EOF
/ABAB/,//+m?DDD?-
,p
q
EOF
where
/ABAB/,//+addresses a range of lines from/ABAB/to the previous match//plus one linemmoves the addressed lines to?DDD?-the previous line matchingDDD, minus one line,pprint the whole buffer
As a one-liner,
printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s file
To edit file in place, replace ,pnqn by ,wqn (write and quit).
Works great! How do we handle this when we have to do this processing on output of a previously processed output? sat if I want to cat file and then do this processing after that, how do I do it?
– Pratap
Feb 24 at 7:10
@Pratap yes you can - but it's not just a matter of piping the previous command output, sinceedreads its commands via standard input. Instead, you have to pass the command as a special "file", preceding it with a!character e.g.printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s !'cat file'.
– steeldriver
Feb 24 at 14:20
add a comment |
NOTE: I'm assuming your data does not have blank lines between each entry; if it does, then you will need to address four lines i.e. change + to +3
With GNU ed:
$ ed -s file <<EOF
/ABAB/,//+m?DDD?-
,p
q
EOF
where
/ABAB/,//+addresses a range of lines from/ABAB/to the previous match//plus one linemmoves the addressed lines to?DDD?-the previous line matchingDDD, minus one line,pprint the whole buffer
As a one-liner,
printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s file
To edit file in place, replace ,pnqn by ,wqn (write and quit).
NOTE: I'm assuming your data does not have blank lines between each entry; if it does, then you will need to address four lines i.e. change + to +3
With GNU ed:
$ ed -s file <<EOF
/ABAB/,//+m?DDD?-
,p
q
EOF
where
/ABAB/,//+addresses a range of lines from/ABAB/to the previous match//plus one linemmoves the addressed lines to?DDD?-the previous line matchingDDD, minus one line,pprint the whole buffer
As a one-liner,
printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s file
To edit file in place, replace ,pnqn by ,wqn (write and quit).
answered Feb 24 at 4:01
steeldriversteeldriver
37.2k45287
37.2k45287
Works great! How do we handle this when we have to do this processing on output of a previously processed output? sat if I want to cat file and then do this processing after that, how do I do it?
– Pratap
Feb 24 at 7:10
@Pratap yes you can - but it's not just a matter of piping the previous command output, sinceedreads its commands via standard input. Instead, you have to pass the command as a special "file", preceding it with a!character e.g.printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s !'cat file'.
– steeldriver
Feb 24 at 14:20
add a comment |
Works great! How do we handle this when we have to do this processing on output of a previously processed output? sat if I want to cat file and then do this processing after that, how do I do it?
– Pratap
Feb 24 at 7:10
@Pratap yes you can - but it's not just a matter of piping the previous command output, sinceedreads its commands via standard input. Instead, you have to pass the command as a special "file", preceding it with a!character e.g.printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s !'cat file'.
– steeldriver
Feb 24 at 14:20
Works great! How do we handle this when we have to do this processing on output of a previously processed output? sat if I want to cat file and then do this processing after that, how do I do it?
– Pratap
Feb 24 at 7:10
Works great! How do we handle this when we have to do this processing on output of a previously processed output? sat if I want to cat file and then do this processing after that, how do I do it?
– Pratap
Feb 24 at 7:10
@Pratap yes you can - but it's not just a matter of piping the previous command output, since
ed reads its commands via standard input. Instead, you have to pass the command as a special "file", preceding it with a ! character e.g. printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s !'cat file'.– steeldriver
Feb 24 at 14:20
@Pratap yes you can - but it's not just a matter of piping the previous command output, since
ed reads its commands via standard input. Instead, you have to pass the command as a special "file", preceding it with a ! character e.g. printf '/ABAB/,//+m?DDD?-n,pnqn' | ed -s !'cat file'.– steeldriver
Feb 24 at 14:20
add a comment |
You wanted with sed so you can do it as shown:
sed -e '
/DDD/,/ABAB/! b
H;/ABAB/!$!d;;g
s/(n.*)n(.*)/21/
' input.txt
This gets straightforward with the ed editor:
ed -s input.file - <<eof
/ABAB/m?DDD?-
wq
eof
add a comment |
You wanted with sed so you can do it as shown:
sed -e '
/DDD/,/ABAB/! b
H;/ABAB/!$!d;;g
s/(n.*)n(.*)/21/
' input.txt
This gets straightforward with the ed editor:
ed -s input.file - <<eof
/ABAB/m?DDD?-
wq
eof
add a comment |
You wanted with sed so you can do it as shown:
sed -e '
/DDD/,/ABAB/! b
H;/ABAB/!$!d;;g
s/(n.*)n(.*)/21/
' input.txt
This gets straightforward with the ed editor:
ed -s input.file - <<eof
/ABAB/m?DDD?-
wq
eof
You wanted with sed so you can do it as shown:
sed -e '
/DDD/,/ABAB/! b
H;/ABAB/!$!d;;g
s/(n.*)n(.*)/21/
' input.txt
This gets straightforward with the ed editor:
ed -s input.file - <<eof
/ABAB/m?DDD?-
wq
eof
edited Feb 24 at 4:14
answered Feb 24 at 3:59
Rakesh SharmaRakesh Sharma
342115
342115
add a comment |
add a comment |
Python (single read)
Reading a file in one and storing what's between the two patterns can be done as so:
#!/usr/bin/env python3
import sys
flag=False
vals =
with open(sys.argv[1]) as fd:
for line in fd:
if line.strip() == "DDD" or flag:
# encountered line where we should stop appending values
if line.strip() == "ABAB":
flag = False
# print the line and two others, then move in what was between originally
print(line.strip())
for i in range(2):
print(fd.readline().strip())
print("n".join(vals))
continue
# store values while we haven't hit ABAB
flag = True
vals.append(line.strip())
continue
print(line.strip())
Python ( double read)
Re-using original awk idea I had to read the file twice, we can do the same in Python:
#!/usr/bin/env python3
import sys
flag_pos,match = 0,0
vals =
with open(sys.argv[1]) as fd:
for index, line in enumerate(fd):
if line.strip() == "DDD":
flag_pos = index
if line.strip() == "ABAB":
vals.append(line.strip())
fd.readline()
vals.append(fd.readline().strip())
with open(sys.argv[1]) as fd:
for index,line in enumerate(fd):
if index == flag_pos:
print("nn".join(vals),"n")
if line.strip() in vals:
fd.readline()
continue
print(line.strip())
This script can be saved as movelines.py and called as ./movelines.py input.txt
AWK
This is doable in gawk probably much more easily than sed:
$ awk 'NR==FNR && $0=="ABAB" a[i++]=$0;getline;getline; a[i++]=$0; ; NR!=FNR if($0=="DDD") for(val in a) printf "%snn",a[val]; if($0 == "ABAB") getline;getline;getline; print $0 ' input.txt input.txt
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
The trick here is that we pass the file to awk twice for reading, and distinguish between first reading that finds the lines we want to move and second reading where we actually move them.
If your actual file does not have blank lines as in the example you provided, you just need one getline instead of two and "%sn" in the second part of the code will suffice.
For readability, here's a multipline version of the code with comments:
# on first reading NR != FNR,
# so lets store ABAB and the other line into array
awk 'NR==FNR && $0=="ABAB"
# i variable will be initialized once incremented first time
a[i++]=$0;getline;getline; a[i++]=$0;
;
# Here we are reading the same file second time
NR!=FNR
if($0=="DDD")
for(val in a)
printf "%snn",a[val];
# Skip what we matched already
if ($0 == "ABAB")
getline;
getline;
getline;
print $0
' input.txt input.txt
add a comment |
Python (single read)
Reading a file in one and storing what's between the two patterns can be done as so:
#!/usr/bin/env python3
import sys
flag=False
vals =
with open(sys.argv[1]) as fd:
for line in fd:
if line.strip() == "DDD" or flag:
# encountered line where we should stop appending values
if line.strip() == "ABAB":
flag = False
# print the line and two others, then move in what was between originally
print(line.strip())
for i in range(2):
print(fd.readline().strip())
print("n".join(vals))
continue
# store values while we haven't hit ABAB
flag = True
vals.append(line.strip())
continue
print(line.strip())
Python ( double read)
Re-using original awk idea I had to read the file twice, we can do the same in Python:
#!/usr/bin/env python3
import sys
flag_pos,match = 0,0
vals =
with open(sys.argv[1]) as fd:
for index, line in enumerate(fd):
if line.strip() == "DDD":
flag_pos = index
if line.strip() == "ABAB":
vals.append(line.strip())
fd.readline()
vals.append(fd.readline().strip())
with open(sys.argv[1]) as fd:
for index,line in enumerate(fd):
if index == flag_pos:
print("nn".join(vals),"n")
if line.strip() in vals:
fd.readline()
continue
print(line.strip())
This script can be saved as movelines.py and called as ./movelines.py input.txt
AWK
This is doable in gawk probably much more easily than sed:
$ awk 'NR==FNR && $0=="ABAB" a[i++]=$0;getline;getline; a[i++]=$0; ; NR!=FNR if($0=="DDD") for(val in a) printf "%snn",a[val]; if($0 == "ABAB") getline;getline;getline; print $0 ' input.txt input.txt
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
The trick here is that we pass the file to awk twice for reading, and distinguish between first reading that finds the lines we want to move and second reading where we actually move them.
If your actual file does not have blank lines as in the example you provided, you just need one getline instead of two and "%sn" in the second part of the code will suffice.
For readability, here's a multipline version of the code with comments:
# on first reading NR != FNR,
# so lets store ABAB and the other line into array
awk 'NR==FNR && $0=="ABAB"
# i variable will be initialized once incremented first time
a[i++]=$0;getline;getline; a[i++]=$0;
;
# Here we are reading the same file second time
NR!=FNR
if($0=="DDD")
for(val in a)
printf "%snn",a[val];
# Skip what we matched already
if ($0 == "ABAB")
getline;
getline;
getline;
print $0
' input.txt input.txt
add a comment |
Python (single read)
Reading a file in one and storing what's between the two patterns can be done as so:
#!/usr/bin/env python3
import sys
flag=False
vals =
with open(sys.argv[1]) as fd:
for line in fd:
if line.strip() == "DDD" or flag:
# encountered line where we should stop appending values
if line.strip() == "ABAB":
flag = False
# print the line and two others, then move in what was between originally
print(line.strip())
for i in range(2):
print(fd.readline().strip())
print("n".join(vals))
continue
# store values while we haven't hit ABAB
flag = True
vals.append(line.strip())
continue
print(line.strip())
Python ( double read)
Re-using original awk idea I had to read the file twice, we can do the same in Python:
#!/usr/bin/env python3
import sys
flag_pos,match = 0,0
vals =
with open(sys.argv[1]) as fd:
for index, line in enumerate(fd):
if line.strip() == "DDD":
flag_pos = index
if line.strip() == "ABAB":
vals.append(line.strip())
fd.readline()
vals.append(fd.readline().strip())
with open(sys.argv[1]) as fd:
for index,line in enumerate(fd):
if index == flag_pos:
print("nn".join(vals),"n")
if line.strip() in vals:
fd.readline()
continue
print(line.strip())
This script can be saved as movelines.py and called as ./movelines.py input.txt
AWK
This is doable in gawk probably much more easily than sed:
$ awk 'NR==FNR && $0=="ABAB" a[i++]=$0;getline;getline; a[i++]=$0; ; NR!=FNR if($0=="DDD") for(val in a) printf "%snn",a[val]; if($0 == "ABAB") getline;getline;getline; print $0 ' input.txt input.txt
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
The trick here is that we pass the file to awk twice for reading, and distinguish between first reading that finds the lines we want to move and second reading where we actually move them.
If your actual file does not have blank lines as in the example you provided, you just need one getline instead of two and "%sn" in the second part of the code will suffice.
For readability, here's a multipline version of the code with comments:
# on first reading NR != FNR,
# so lets store ABAB and the other line into array
awk 'NR==FNR && $0=="ABAB"
# i variable will be initialized once incremented first time
a[i++]=$0;getline;getline; a[i++]=$0;
;
# Here we are reading the same file second time
NR!=FNR
if($0=="DDD")
for(val in a)
printf "%snn",a[val];
# Skip what we matched already
if ($0 == "ABAB")
getline;
getline;
getline;
print $0
' input.txt input.txt
Python (single read)
Reading a file in one and storing what's between the two patterns can be done as so:
#!/usr/bin/env python3
import sys
flag=False
vals =
with open(sys.argv[1]) as fd:
for line in fd:
if line.strip() == "DDD" or flag:
# encountered line where we should stop appending values
if line.strip() == "ABAB":
flag = False
# print the line and two others, then move in what was between originally
print(line.strip())
for i in range(2):
print(fd.readline().strip())
print("n".join(vals))
continue
# store values while we haven't hit ABAB
flag = True
vals.append(line.strip())
continue
print(line.strip())
Python ( double read)
Re-using original awk idea I had to read the file twice, we can do the same in Python:
#!/usr/bin/env python3
import sys
flag_pos,match = 0,0
vals =
with open(sys.argv[1]) as fd:
for index, line in enumerate(fd):
if line.strip() == "DDD":
flag_pos = index
if line.strip() == "ABAB":
vals.append(line.strip())
fd.readline()
vals.append(fd.readline().strip())
with open(sys.argv[1]) as fd:
for index,line in enumerate(fd):
if index == flag_pos:
print("nn".join(vals),"n")
if line.strip() in vals:
fd.readline()
continue
print(line.strip())
This script can be saved as movelines.py and called as ./movelines.py input.txt
AWK
This is doable in gawk probably much more easily than sed:
$ awk 'NR==FNR && $0=="ABAB" a[i++]=$0;getline;getline; a[i++]=$0; ; NR!=FNR if($0=="DDD") for(val in a) printf "%snn",a[val]; if($0 == "ABAB") getline;getline;getline; print $0 ' input.txt input.txt
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
The trick here is that we pass the file to awk twice for reading, and distinguish between first reading that finds the lines we want to move and second reading where we actually move them.
If your actual file does not have blank lines as in the example you provided, you just need one getline instead of two and "%sn" in the second part of the code will suffice.
For readability, here's a multipline version of the code with comments:
# on first reading NR != FNR,
# so lets store ABAB and the other line into array
awk 'NR==FNR && $0=="ABAB"
# i variable will be initialized once incremented first time
a[i++]=$0;getline;getline; a[i++]=$0;
;
# Here we are reading the same file second time
NR!=FNR
if($0=="DDD")
for(val in a)
printf "%snn",a[val];
# Skip what we matched already
if ($0 == "ABAB")
getline;
getline;
getline;
print $0
' input.txt input.txt
edited Feb 24 at 4:38
answered Feb 24 at 3:39
Sergiy KolodyazhnyySergiy Kolodyazhnyy
10.6k42763
10.6k42763
add a comment |
add a comment |
I have done by below method
command
Step1: h=`sed -n '/[A-Za-z]4/p' filename| sed -n '1p'`
step2:m=`sed -n '/[A-Za-z]4/p' filename| sed -n '2p'`
step3
sed '/[A-Z]4/d' filename|sed "/CCC/s/.*/&nn$hnn$m/g"| sed '/^$/d'
output
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
add a comment |
I have done by below method
command
Step1: h=`sed -n '/[A-Za-z]4/p' filename| sed -n '1p'`
step2:m=`sed -n '/[A-Za-z]4/p' filename| sed -n '2p'`
step3
sed '/[A-Z]4/d' filename|sed "/CCC/s/.*/&nn$hnn$m/g"| sed '/^$/d'
output
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
add a comment |
I have done by below method
command
Step1: h=`sed -n '/[A-Za-z]4/p' filename| sed -n '1p'`
step2:m=`sed -n '/[A-Za-z]4/p' filename| sed -n '2p'`
step3
sed '/[A-Z]4/d' filename|sed "/CCC/s/.*/&nn$hnn$m/g"| sed '/^$/d'
output
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
I have done by below method
command
Step1: h=`sed -n '/[A-Za-z]4/p' filename| sed -n '1p'`
step2:m=`sed -n '/[A-Za-z]4/p' filename| sed -n '2p'`
step3
sed '/[A-Z]4/d' filename|sed "/CCC/s/.*/&nn$hnn$m/g"| sed '/^$/d'
output
AAA
BBB
CCC
ABAB
ACAC
DDD
EEE
FFF
GGG
HHH
answered Feb 24 at 16:18
Praveen Kumar BSPraveen Kumar BS
1,6351311
1,6351311
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f502622%2fmove-few-lines-after-a-pattern-match-to-another-position-just-before-another-ma%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Are there really blank lines between each entry?
– steeldriver
Feb 24 at 3:32