Replace range of lines with range of lines (sed or others)
Clash Royale CLAN TAG#URR8PPP
up vote
3
down vote
favorite
I have two textfiles: file1
and file2
, both with several lines.
$ cat file1
line one
line two
line three
line four
line five
$ cat file2
line A
line B
line C
line D
line E
line F
I would like to substitute a range of lines of file1
(from line 1_start
to line 1_end
) with a range of lines of file2
(from line 2_start
to line 2_end
).
For example, substitute lines 2,4
in file1
with lines 3,5
from file2
.
What I only could do till now is to extract the needed lines from file2
with
$ sed -n 3,5p file2
But it doesn't help putting them in file1
. Is it possible with sed
? If not, is it possible with a similar tool?
text-processing sed
add a comment |Â
up vote
3
down vote
favorite
I have two textfiles: file1
and file2
, both with several lines.
$ cat file1
line one
line two
line three
line four
line five
$ cat file2
line A
line B
line C
line D
line E
line F
I would like to substitute a range of lines of file1
(from line 1_start
to line 1_end
) with a range of lines of file2
(from line 2_start
to line 2_end
).
For example, substitute lines 2,4
in file1
with lines 3,5
from file2
.
What I only could do till now is to extract the needed lines from file2
with
$ sed -n 3,5p file2
But it doesn't help putting them in file1
. Is it possible with sed
? If not, is it possible with a similar tool?
text-processing sed
1
@Sundeep I just edited the question as you suggested.
â BowPark
Dec 6 '17 at 11:23
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I have two textfiles: file1
and file2
, both with several lines.
$ cat file1
line one
line two
line three
line four
line five
$ cat file2
line A
line B
line C
line D
line E
line F
I would like to substitute a range of lines of file1
(from line 1_start
to line 1_end
) with a range of lines of file2
(from line 2_start
to line 2_end
).
For example, substitute lines 2,4
in file1
with lines 3,5
from file2
.
What I only could do till now is to extract the needed lines from file2
with
$ sed -n 3,5p file2
But it doesn't help putting them in file1
. Is it possible with sed
? If not, is it possible with a similar tool?
text-processing sed
I have two textfiles: file1
and file2
, both with several lines.
$ cat file1
line one
line two
line three
line four
line five
$ cat file2
line A
line B
line C
line D
line E
line F
I would like to substitute a range of lines of file1
(from line 1_start
to line 1_end
) with a range of lines of file2
(from line 2_start
to line 2_end
).
For example, substitute lines 2,4
in file1
with lines 3,5
from file2
.
What I only could do till now is to extract the needed lines from file2
with
$ sed -n 3,5p file2
But it doesn't help putting them in file1
. Is it possible with sed
? If not, is it possible with a similar tool?
text-processing sed
edited Dec 6 '17 at 11:22
asked Dec 6 '17 at 10:57
BowPark
1,45682139
1,45682139
1
@Sundeep I just edited the question as you suggested.
â BowPark
Dec 6 '17 at 11:23
add a comment |Â
1
@Sundeep I just edited the question as you suggested.
â BowPark
Dec 6 '17 at 11:23
1
1
@Sundeep I just edited the question as you suggested.
â BowPark
Dec 6 '17 at 11:23
@Sundeep I just edited the question as you suggested.
â BowPark
Dec 6 '17 at 11:23
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
7
down vote
sed
can print a given range of lines with something like this:
sed -n 'X,Yp' filename
Where X
is first line in a range and Y
is the last line, both inclusive. -n
tells sed
not to print anything unless explicitly told to do so and that's what the p
following the range does.
So you can easily call this three times, appending to a temporary file, then move that file to wherever you want. You can also combine them all using cat
and process substitution as this example shows (I'm using line numbers I just pulled out of thin air; $
is last line in a file):
cat <(sed -n '1,5p' file1) <(sed -n '10,12p' file2) <(sed -n '9,$p' file1) > file1.tmp && mv file1.tmp file1
Here, we'd be replacing lines 6, 7 and 8 in file1
with lines 10, 11 and 12 from file2
.
Update: Thanks to @MiniMax for pointing out that cat
and the process substitution can be avoided by doing the following:
sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1.tmp && mv file1.tmp file1
KISS, after all. :)
This is inefficient, especially with huge input files (you're reading the entirefile1
twice and the entirefile2
).
â don_crissti
Dec 6 '17 at 13:34
1
@don_crissti Meh. You're nitpicking. Yes reading the file twice is relatively inefficient. So is using shell scripts. But go run a million liner throughsed
and see how long it takes. Less than a second on the very slow machine I'm sitting at. It's pointless to worry about performance here short of OP telling us they're dealing with HUGE files. By the way, "especially with huge files"? What does that have to do with efficiency? Put a two liner through it or a 4B line monster...same efficiency.
â B Layer
Dec 6 '17 at 14:23
1
1. It's not pointless to worry about efficiency here (or on any similar site). You've been here long enough to know that you're not posting only for this particular OP but for future visitors too. Even if this was the only person in the world to benefit from my answer I would still want to do it in the most efficient way (and it's no big deal really to add someq
s to yoursed
s). 2. You're right. What I meant was "the difference between efficient and inefficient would be more visible with huge files"... I'm lazy (typing on my phone).
â don_crissti
Dec 6 '17 at 14:42
1
We're going to have to agree to disagree. I'm a professional sw dev/programmer for 20 years (you may have similar credentials...my point is not to have a size measuring contest just to tell you where I'm coming from) and KISS and "don't optimize until you need to" are the accepted best practices I embrace. I will always favor a bit less complexity over a modicum of performance gain. (I concede, though, that "pointless" was not the best choice of words.)
â B Layer
Dec 6 '17 at 15:11
Why not just:sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1
?cat
doesn't needed, process substitution doesn't needed.
â MiniMax
Dec 6 '17 at 21:05
 |Â
show 2 more comments
up vote
4
down vote
Another way to do with sed
is using r
command, handy if -i
inplace option has to be used as well
$ sed -n '3,5p; 5q;' f2 | sed -e '2r /dev/stdin' -e '2,4d' f1
line one
line C
line D
line E
line five
$ # if /dev/stdin is not supported
$ sed -n '3,5p; 5q;' f2 > t1
$ sed -e '2r t1' -e '2,4d' f1
Thanks to don_crissti for reminding that we could quit as soon as required line(s) are obtained from file 2.
add a comment |Â
up vote
2
down vote
With huge input files this may be faster:
# replacing lines m1,m2 from file1 with lines n1,n2 from file2
m1=2; m2=4; n1=3; n2=5
head -n $((m1-1)); head -n $((n1-1)) >/dev/null; head -n $((n2-n1+1));
<file2; head -n $((m2-m1+1)) >/dev/null; cat; <file1
It's explained here, the only difference being the one-line ranges in that particular case.
add a comment |Â
up vote
1
down vote
I've started doing everything with Python lately, so here's a Python program that does what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""replace_range.py"""
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"matchfile",
help="File in which to replace lines",
)
parser.add_argument(
"matchrange",
help="Comma-separated range of Lines to match and replace",
)
parser.add_argument(
"replacementfile",
help="File from which to get replacement lines"
)
parser.add_argument(
"replacementrange",
help="Comma-separated range of lines from which to get replacement"
)
if __name__=="__main__":
# Parse the command-line arguments
args = parser.parse_args()
# Open the files
with
open(args.matchfile, 'r') as matchfile,
open(args.replacementfile, 'r') as replacementfile:
# Get the input from the match file as a list of strings
matchlines = matchfile.readlines()
# Get the match range (NOTE: shitf by -1 to convert to zero-indexed list)
mstart = int(args.matchrange.strip().split(',')[0]) - 1
mend = int(args.matchrange.strip().split(',')[1]) - 1
# Get the input from the replacement file as a list of strings
replacementlines = replacementfile.readlines()
# Get the replacement range (NOTE: shitf by -1 to convert to zero-indexed list)
rstart = int(args.replacementrange.strip().split(',')[0]) -1
rend = int(args.replacementrange.strip().split(',')[1]) - 1
# Replace the match text with the replacement text
outputlines = matchlines[0:mstart] + replacementlines[rstart:rend+1] + matchlines[mend+1:]
# Output the result
sys.stdout.write(''.join(outputlines))
And here's what it looks like in action:
user@host:~$ python replace_range.py file1 2,3 file2 2,4
line one
line B
line C
line D
line four
line five
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
sed
can print a given range of lines with something like this:
sed -n 'X,Yp' filename
Where X
is first line in a range and Y
is the last line, both inclusive. -n
tells sed
not to print anything unless explicitly told to do so and that's what the p
following the range does.
So you can easily call this three times, appending to a temporary file, then move that file to wherever you want. You can also combine them all using cat
and process substitution as this example shows (I'm using line numbers I just pulled out of thin air; $
is last line in a file):
cat <(sed -n '1,5p' file1) <(sed -n '10,12p' file2) <(sed -n '9,$p' file1) > file1.tmp && mv file1.tmp file1
Here, we'd be replacing lines 6, 7 and 8 in file1
with lines 10, 11 and 12 from file2
.
Update: Thanks to @MiniMax for pointing out that cat
and the process substitution can be avoided by doing the following:
sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1.tmp && mv file1.tmp file1
KISS, after all. :)
This is inefficient, especially with huge input files (you're reading the entirefile1
twice and the entirefile2
).
â don_crissti
Dec 6 '17 at 13:34
1
@don_crissti Meh. You're nitpicking. Yes reading the file twice is relatively inefficient. So is using shell scripts. But go run a million liner throughsed
and see how long it takes. Less than a second on the very slow machine I'm sitting at. It's pointless to worry about performance here short of OP telling us they're dealing with HUGE files. By the way, "especially with huge files"? What does that have to do with efficiency? Put a two liner through it or a 4B line monster...same efficiency.
â B Layer
Dec 6 '17 at 14:23
1
1. It's not pointless to worry about efficiency here (or on any similar site). You've been here long enough to know that you're not posting only for this particular OP but for future visitors too. Even if this was the only person in the world to benefit from my answer I would still want to do it in the most efficient way (and it's no big deal really to add someq
s to yoursed
s). 2. You're right. What I meant was "the difference between efficient and inefficient would be more visible with huge files"... I'm lazy (typing on my phone).
â don_crissti
Dec 6 '17 at 14:42
1
We're going to have to agree to disagree. I'm a professional sw dev/programmer for 20 years (you may have similar credentials...my point is not to have a size measuring contest just to tell you where I'm coming from) and KISS and "don't optimize until you need to" are the accepted best practices I embrace. I will always favor a bit less complexity over a modicum of performance gain. (I concede, though, that "pointless" was not the best choice of words.)
â B Layer
Dec 6 '17 at 15:11
Why not just:sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1
?cat
doesn't needed, process substitution doesn't needed.
â MiniMax
Dec 6 '17 at 21:05
 |Â
show 2 more comments
up vote
7
down vote
sed
can print a given range of lines with something like this:
sed -n 'X,Yp' filename
Where X
is first line in a range and Y
is the last line, both inclusive. -n
tells sed
not to print anything unless explicitly told to do so and that's what the p
following the range does.
So you can easily call this three times, appending to a temporary file, then move that file to wherever you want. You can also combine them all using cat
and process substitution as this example shows (I'm using line numbers I just pulled out of thin air; $
is last line in a file):
cat <(sed -n '1,5p' file1) <(sed -n '10,12p' file2) <(sed -n '9,$p' file1) > file1.tmp && mv file1.tmp file1
Here, we'd be replacing lines 6, 7 and 8 in file1
with lines 10, 11 and 12 from file2
.
Update: Thanks to @MiniMax for pointing out that cat
and the process substitution can be avoided by doing the following:
sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1.tmp && mv file1.tmp file1
KISS, after all. :)
This is inefficient, especially with huge input files (you're reading the entirefile1
twice and the entirefile2
).
â don_crissti
Dec 6 '17 at 13:34
1
@don_crissti Meh. You're nitpicking. Yes reading the file twice is relatively inefficient. So is using shell scripts. But go run a million liner throughsed
and see how long it takes. Less than a second on the very slow machine I'm sitting at. It's pointless to worry about performance here short of OP telling us they're dealing with HUGE files. By the way, "especially with huge files"? What does that have to do with efficiency? Put a two liner through it or a 4B line monster...same efficiency.
â B Layer
Dec 6 '17 at 14:23
1
1. It's not pointless to worry about efficiency here (or on any similar site). You've been here long enough to know that you're not posting only for this particular OP but for future visitors too. Even if this was the only person in the world to benefit from my answer I would still want to do it in the most efficient way (and it's no big deal really to add someq
s to yoursed
s). 2. You're right. What I meant was "the difference between efficient and inefficient would be more visible with huge files"... I'm lazy (typing on my phone).
â don_crissti
Dec 6 '17 at 14:42
1
We're going to have to agree to disagree. I'm a professional sw dev/programmer for 20 years (you may have similar credentials...my point is not to have a size measuring contest just to tell you where I'm coming from) and KISS and "don't optimize until you need to" are the accepted best practices I embrace. I will always favor a bit less complexity over a modicum of performance gain. (I concede, though, that "pointless" was not the best choice of words.)
â B Layer
Dec 6 '17 at 15:11
Why not just:sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1
?cat
doesn't needed, process substitution doesn't needed.
â MiniMax
Dec 6 '17 at 21:05
 |Â
show 2 more comments
up vote
7
down vote
up vote
7
down vote
sed
can print a given range of lines with something like this:
sed -n 'X,Yp' filename
Where X
is first line in a range and Y
is the last line, both inclusive. -n
tells sed
not to print anything unless explicitly told to do so and that's what the p
following the range does.
So you can easily call this three times, appending to a temporary file, then move that file to wherever you want. You can also combine them all using cat
and process substitution as this example shows (I'm using line numbers I just pulled out of thin air; $
is last line in a file):
cat <(sed -n '1,5p' file1) <(sed -n '10,12p' file2) <(sed -n '9,$p' file1) > file1.tmp && mv file1.tmp file1
Here, we'd be replacing lines 6, 7 and 8 in file1
with lines 10, 11 and 12 from file2
.
Update: Thanks to @MiniMax for pointing out that cat
and the process substitution can be avoided by doing the following:
sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1.tmp && mv file1.tmp file1
KISS, after all. :)
sed
can print a given range of lines with something like this:
sed -n 'X,Yp' filename
Where X
is first line in a range and Y
is the last line, both inclusive. -n
tells sed
not to print anything unless explicitly told to do so and that's what the p
following the range does.
So you can easily call this three times, appending to a temporary file, then move that file to wherever you want. You can also combine them all using cat
and process substitution as this example shows (I'm using line numbers I just pulled out of thin air; $
is last line in a file):
cat <(sed -n '1,5p' file1) <(sed -n '10,12p' file2) <(sed -n '9,$p' file1) > file1.tmp && mv file1.tmp file1
Here, we'd be replacing lines 6, 7 and 8 in file1
with lines 10, 11 and 12 from file2
.
Update: Thanks to @MiniMax for pointing out that cat
and the process substitution can be avoided by doing the following:
sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1.tmp && mv file1.tmp file1
KISS, after all. :)
edited Dec 6 '17 at 23:03
answered Dec 6 '17 at 11:07
B Layer
3,9091525
3,9091525
This is inefficient, especially with huge input files (you're reading the entirefile1
twice and the entirefile2
).
â don_crissti
Dec 6 '17 at 13:34
1
@don_crissti Meh. You're nitpicking. Yes reading the file twice is relatively inefficient. So is using shell scripts. But go run a million liner throughsed
and see how long it takes. Less than a second on the very slow machine I'm sitting at. It's pointless to worry about performance here short of OP telling us they're dealing with HUGE files. By the way, "especially with huge files"? What does that have to do with efficiency? Put a two liner through it or a 4B line monster...same efficiency.
â B Layer
Dec 6 '17 at 14:23
1
1. It's not pointless to worry about efficiency here (or on any similar site). You've been here long enough to know that you're not posting only for this particular OP but for future visitors too. Even if this was the only person in the world to benefit from my answer I would still want to do it in the most efficient way (and it's no big deal really to add someq
s to yoursed
s). 2. You're right. What I meant was "the difference between efficient and inefficient would be more visible with huge files"... I'm lazy (typing on my phone).
â don_crissti
Dec 6 '17 at 14:42
1
We're going to have to agree to disagree. I'm a professional sw dev/programmer for 20 years (you may have similar credentials...my point is not to have a size measuring contest just to tell you where I'm coming from) and KISS and "don't optimize until you need to" are the accepted best practices I embrace. I will always favor a bit less complexity over a modicum of performance gain. (I concede, though, that "pointless" was not the best choice of words.)
â B Layer
Dec 6 '17 at 15:11
Why not just:sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1
?cat
doesn't needed, process substitution doesn't needed.
â MiniMax
Dec 6 '17 at 21:05
 |Â
show 2 more comments
This is inefficient, especially with huge input files (you're reading the entirefile1
twice and the entirefile2
).
â don_crissti
Dec 6 '17 at 13:34
1
@don_crissti Meh. You're nitpicking. Yes reading the file twice is relatively inefficient. So is using shell scripts. But go run a million liner throughsed
and see how long it takes. Less than a second on the very slow machine I'm sitting at. It's pointless to worry about performance here short of OP telling us they're dealing with HUGE files. By the way, "especially with huge files"? What does that have to do with efficiency? Put a two liner through it or a 4B line monster...same efficiency.
â B Layer
Dec 6 '17 at 14:23
1
1. It's not pointless to worry about efficiency here (or on any similar site). You've been here long enough to know that you're not posting only for this particular OP but for future visitors too. Even if this was the only person in the world to benefit from my answer I would still want to do it in the most efficient way (and it's no big deal really to add someq
s to yoursed
s). 2. You're right. What I meant was "the difference between efficient and inefficient would be more visible with huge files"... I'm lazy (typing on my phone).
â don_crissti
Dec 6 '17 at 14:42
1
We're going to have to agree to disagree. I'm a professional sw dev/programmer for 20 years (you may have similar credentials...my point is not to have a size measuring contest just to tell you where I'm coming from) and KISS and "don't optimize until you need to" are the accepted best practices I embrace. I will always favor a bit less complexity over a modicum of performance gain. (I concede, though, that "pointless" was not the best choice of words.)
â B Layer
Dec 6 '17 at 15:11
Why not just:sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1
?cat
doesn't needed, process substitution doesn't needed.
â MiniMax
Dec 6 '17 at 21:05
This is inefficient, especially with huge input files (you're reading the entire
file1
twice and the entire file2
).â don_crissti
Dec 6 '17 at 13:34
This is inefficient, especially with huge input files (you're reading the entire
file1
twice and the entire file2
).â don_crissti
Dec 6 '17 at 13:34
1
1
@don_crissti Meh. You're nitpicking. Yes reading the file twice is relatively inefficient. So is using shell scripts. But go run a million liner through
sed
and see how long it takes. Less than a second on the very slow machine I'm sitting at. It's pointless to worry about performance here short of OP telling us they're dealing with HUGE files. By the way, "especially with huge files"? What does that have to do with efficiency? Put a two liner through it or a 4B line monster...same efficiency.â B Layer
Dec 6 '17 at 14:23
@don_crissti Meh. You're nitpicking. Yes reading the file twice is relatively inefficient. So is using shell scripts. But go run a million liner through
sed
and see how long it takes. Less than a second on the very slow machine I'm sitting at. It's pointless to worry about performance here short of OP telling us they're dealing with HUGE files. By the way, "especially with huge files"? What does that have to do with efficiency? Put a two liner through it or a 4B line monster...same efficiency.â B Layer
Dec 6 '17 at 14:23
1
1
1. It's not pointless to worry about efficiency here (or on any similar site). You've been here long enough to know that you're not posting only for this particular OP but for future visitors too. Even if this was the only person in the world to benefit from my answer I would still want to do it in the most efficient way (and it's no big deal really to add some
q
s to your sed
s). 2. You're right. What I meant was "the difference between efficient and inefficient would be more visible with huge files"... I'm lazy (typing on my phone).â don_crissti
Dec 6 '17 at 14:42
1. It's not pointless to worry about efficiency here (or on any similar site). You've been here long enough to know that you're not posting only for this particular OP but for future visitors too. Even if this was the only person in the world to benefit from my answer I would still want to do it in the most efficient way (and it's no big deal really to add some
q
s to your sed
s). 2. You're right. What I meant was "the difference between efficient and inefficient would be more visible with huge files"... I'm lazy (typing on my phone).â don_crissti
Dec 6 '17 at 14:42
1
1
We're going to have to agree to disagree. I'm a professional sw dev/programmer for 20 years (you may have similar credentials...my point is not to have a size measuring contest just to tell you where I'm coming from) and KISS and "don't optimize until you need to" are the accepted best practices I embrace. I will always favor a bit less complexity over a modicum of performance gain. (I concede, though, that "pointless" was not the best choice of words.)
â B Layer
Dec 6 '17 at 15:11
We're going to have to agree to disagree. I'm a professional sw dev/programmer for 20 years (you may have similar credentials...my point is not to have a size measuring contest just to tell you where I'm coming from) and KISS and "don't optimize until you need to" are the accepted best practices I embrace. I will always favor a bit less complexity over a modicum of performance gain. (I concede, though, that "pointless" was not the best choice of words.)
â B Layer
Dec 6 '17 at 15:11
Why not just:
sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1
? cat
doesn't needed, process substitution doesn't needed.â MiniMax
Dec 6 '17 at 21:05
Why not just:
sed -n '1,5p' file1; sed -n '10,12p' file2; sed -n '9,$p' file1; > file1
? cat
doesn't needed, process substitution doesn't needed.â MiniMax
Dec 6 '17 at 21:05
 |Â
show 2 more comments
up vote
4
down vote
Another way to do with sed
is using r
command, handy if -i
inplace option has to be used as well
$ sed -n '3,5p; 5q;' f2 | sed -e '2r /dev/stdin' -e '2,4d' f1
line one
line C
line D
line E
line five
$ # if /dev/stdin is not supported
$ sed -n '3,5p; 5q;' f2 > t1
$ sed -e '2r t1' -e '2,4d' f1
Thanks to don_crissti for reminding that we could quit as soon as required line(s) are obtained from file 2.
add a comment |Â
up vote
4
down vote
Another way to do with sed
is using r
command, handy if -i
inplace option has to be used as well
$ sed -n '3,5p; 5q;' f2 | sed -e '2r /dev/stdin' -e '2,4d' f1
line one
line C
line D
line E
line five
$ # if /dev/stdin is not supported
$ sed -n '3,5p; 5q;' f2 > t1
$ sed -e '2r t1' -e '2,4d' f1
Thanks to don_crissti for reminding that we could quit as soon as required line(s) are obtained from file 2.
add a comment |Â
up vote
4
down vote
up vote
4
down vote
Another way to do with sed
is using r
command, handy if -i
inplace option has to be used as well
$ sed -n '3,5p; 5q;' f2 | sed -e '2r /dev/stdin' -e '2,4d' f1
line one
line C
line D
line E
line five
$ # if /dev/stdin is not supported
$ sed -n '3,5p; 5q;' f2 > t1
$ sed -e '2r t1' -e '2,4d' f1
Thanks to don_crissti for reminding that we could quit as soon as required line(s) are obtained from file 2.
Another way to do with sed
is using r
command, handy if -i
inplace option has to be used as well
$ sed -n '3,5p; 5q;' f2 | sed -e '2r /dev/stdin' -e '2,4d' f1
line one
line C
line D
line E
line five
$ # if /dev/stdin is not supported
$ sed -n '3,5p; 5q;' f2 > t1
$ sed -e '2r t1' -e '2,4d' f1
Thanks to don_crissti for reminding that we could quit as soon as required line(s) are obtained from file 2.
edited Dec 6 '17 at 14:10
answered Dec 6 '17 at 11:57
Sundeep
6,9511826
6,9511826
add a comment |Â
add a comment |Â
up vote
2
down vote
With huge input files this may be faster:
# replacing lines m1,m2 from file1 with lines n1,n2 from file2
m1=2; m2=4; n1=3; n2=5
head -n $((m1-1)); head -n $((n1-1)) >/dev/null; head -n $((n2-n1+1));
<file2; head -n $((m2-m1+1)) >/dev/null; cat; <file1
It's explained here, the only difference being the one-line ranges in that particular case.
add a comment |Â
up vote
2
down vote
With huge input files this may be faster:
# replacing lines m1,m2 from file1 with lines n1,n2 from file2
m1=2; m2=4; n1=3; n2=5
head -n $((m1-1)); head -n $((n1-1)) >/dev/null; head -n $((n2-n1+1));
<file2; head -n $((m2-m1+1)) >/dev/null; cat; <file1
It's explained here, the only difference being the one-line ranges in that particular case.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
With huge input files this may be faster:
# replacing lines m1,m2 from file1 with lines n1,n2 from file2
m1=2; m2=4; n1=3; n2=5
head -n $((m1-1)); head -n $((n1-1)) >/dev/null; head -n $((n2-n1+1));
<file2; head -n $((m2-m1+1)) >/dev/null; cat; <file1
It's explained here, the only difference being the one-line ranges in that particular case.
With huge input files this may be faster:
# replacing lines m1,m2 from file1 with lines n1,n2 from file2
m1=2; m2=4; n1=3; n2=5
head -n $((m1-1)); head -n $((n1-1)) >/dev/null; head -n $((n2-n1+1));
<file2; head -n $((m2-m1+1)) >/dev/null; cat; <file1
It's explained here, the only difference being the one-line ranges in that particular case.
answered Dec 6 '17 at 14:05
don_crissti
46.8k15124153
46.8k15124153
add a comment |Â
add a comment |Â
up vote
1
down vote
I've started doing everything with Python lately, so here's a Python program that does what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""replace_range.py"""
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"matchfile",
help="File in which to replace lines",
)
parser.add_argument(
"matchrange",
help="Comma-separated range of Lines to match and replace",
)
parser.add_argument(
"replacementfile",
help="File from which to get replacement lines"
)
parser.add_argument(
"replacementrange",
help="Comma-separated range of lines from which to get replacement"
)
if __name__=="__main__":
# Parse the command-line arguments
args = parser.parse_args()
# Open the files
with
open(args.matchfile, 'r') as matchfile,
open(args.replacementfile, 'r') as replacementfile:
# Get the input from the match file as a list of strings
matchlines = matchfile.readlines()
# Get the match range (NOTE: shitf by -1 to convert to zero-indexed list)
mstart = int(args.matchrange.strip().split(',')[0]) - 1
mend = int(args.matchrange.strip().split(',')[1]) - 1
# Get the input from the replacement file as a list of strings
replacementlines = replacementfile.readlines()
# Get the replacement range (NOTE: shitf by -1 to convert to zero-indexed list)
rstart = int(args.replacementrange.strip().split(',')[0]) -1
rend = int(args.replacementrange.strip().split(',')[1]) - 1
# Replace the match text with the replacement text
outputlines = matchlines[0:mstart] + replacementlines[rstart:rend+1] + matchlines[mend+1:]
# Output the result
sys.stdout.write(''.join(outputlines))
And here's what it looks like in action:
user@host:~$ python replace_range.py file1 2,3 file2 2,4
line one
line B
line C
line D
line four
line five
add a comment |Â
up vote
1
down vote
I've started doing everything with Python lately, so here's a Python program that does what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""replace_range.py"""
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"matchfile",
help="File in which to replace lines",
)
parser.add_argument(
"matchrange",
help="Comma-separated range of Lines to match and replace",
)
parser.add_argument(
"replacementfile",
help="File from which to get replacement lines"
)
parser.add_argument(
"replacementrange",
help="Comma-separated range of lines from which to get replacement"
)
if __name__=="__main__":
# Parse the command-line arguments
args = parser.parse_args()
# Open the files
with
open(args.matchfile, 'r') as matchfile,
open(args.replacementfile, 'r') as replacementfile:
# Get the input from the match file as a list of strings
matchlines = matchfile.readlines()
# Get the match range (NOTE: shitf by -1 to convert to zero-indexed list)
mstart = int(args.matchrange.strip().split(',')[0]) - 1
mend = int(args.matchrange.strip().split(',')[1]) - 1
# Get the input from the replacement file as a list of strings
replacementlines = replacementfile.readlines()
# Get the replacement range (NOTE: shitf by -1 to convert to zero-indexed list)
rstart = int(args.replacementrange.strip().split(',')[0]) -1
rend = int(args.replacementrange.strip().split(',')[1]) - 1
# Replace the match text with the replacement text
outputlines = matchlines[0:mstart] + replacementlines[rstart:rend+1] + matchlines[mend+1:]
# Output the result
sys.stdout.write(''.join(outputlines))
And here's what it looks like in action:
user@host:~$ python replace_range.py file1 2,3 file2 2,4
line one
line B
line C
line D
line four
line five
add a comment |Â
up vote
1
down vote
up vote
1
down vote
I've started doing everything with Python lately, so here's a Python program that does what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""replace_range.py"""
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"matchfile",
help="File in which to replace lines",
)
parser.add_argument(
"matchrange",
help="Comma-separated range of Lines to match and replace",
)
parser.add_argument(
"replacementfile",
help="File from which to get replacement lines"
)
parser.add_argument(
"replacementrange",
help="Comma-separated range of lines from which to get replacement"
)
if __name__=="__main__":
# Parse the command-line arguments
args = parser.parse_args()
# Open the files
with
open(args.matchfile, 'r') as matchfile,
open(args.replacementfile, 'r') as replacementfile:
# Get the input from the match file as a list of strings
matchlines = matchfile.readlines()
# Get the match range (NOTE: shitf by -1 to convert to zero-indexed list)
mstart = int(args.matchrange.strip().split(',')[0]) - 1
mend = int(args.matchrange.strip().split(',')[1]) - 1
# Get the input from the replacement file as a list of strings
replacementlines = replacementfile.readlines()
# Get the replacement range (NOTE: shitf by -1 to convert to zero-indexed list)
rstart = int(args.replacementrange.strip().split(',')[0]) -1
rend = int(args.replacementrange.strip().split(',')[1]) - 1
# Replace the match text with the replacement text
outputlines = matchlines[0:mstart] + replacementlines[rstart:rend+1] + matchlines[mend+1:]
# Output the result
sys.stdout.write(''.join(outputlines))
And here's what it looks like in action:
user@host:~$ python replace_range.py file1 2,3 file2 2,4
line one
line B
line C
line D
line four
line five
I've started doing everything with Python lately, so here's a Python program that does what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""replace_range.py"""
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"matchfile",
help="File in which to replace lines",
)
parser.add_argument(
"matchrange",
help="Comma-separated range of Lines to match and replace",
)
parser.add_argument(
"replacementfile",
help="File from which to get replacement lines"
)
parser.add_argument(
"replacementrange",
help="Comma-separated range of lines from which to get replacement"
)
if __name__=="__main__":
# Parse the command-line arguments
args = parser.parse_args()
# Open the files
with
open(args.matchfile, 'r') as matchfile,
open(args.replacementfile, 'r') as replacementfile:
# Get the input from the match file as a list of strings
matchlines = matchfile.readlines()
# Get the match range (NOTE: shitf by -1 to convert to zero-indexed list)
mstart = int(args.matchrange.strip().split(',')[0]) - 1
mend = int(args.matchrange.strip().split(',')[1]) - 1
# Get the input from the replacement file as a list of strings
replacementlines = replacementfile.readlines()
# Get the replacement range (NOTE: shitf by -1 to convert to zero-indexed list)
rstart = int(args.replacementrange.strip().split(',')[0]) -1
rend = int(args.replacementrange.strip().split(',')[1]) - 1
# Replace the match text with the replacement text
outputlines = matchlines[0:mstart] + replacementlines[rstart:rend+1] + matchlines[mend+1:]
# Output the result
sys.stdout.write(''.join(outputlines))
And here's what it looks like in action:
user@host:~$ python replace_range.py file1 2,3 file2 2,4
line one
line B
line C
line D
line four
line five
answered Dec 6 '17 at 12:10
igal
4,830930
4,830930
add a comment |Â
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f409167%2freplace-range-of-lines-with-range-of-lines-sed-or-others%23new-answer', 'question_page');
);
Post as a guest
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
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
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
1
@Sundeep I just edited the question as you suggested.
â BowPark
Dec 6 '17 at 11:23