Reputation: 65
I'm trying to copy a line from file1 and write that line into line 10 of file2 using bash.
Here is what I have tried:
sed -e '10i' file2 <file1
Upvotes: 1
Views: 5299
Reputation: 58440
This might work for you (GNU sed & Bash):
sed $'10{e sed "1!d" file1\n;d}' file2
or another way using a pipe:
sed '1!d' file1 | sed -e '10{r /dev/stdin' -e 'd}' file2
or a third way (perhaps more intuitively but only works for a singleton replacement line):
sed '10\c'$(sed '1!d' file1) file2
Upvotes: 0
Reputation: 2233
If you are using GNU sed
, this:
sed -n '1p' choose-line-here.txt | sed -i '10r /dev/stdin' insert-here.txt
will insert line 1 from choose-line-here.txt
after line 10 in insert-here.txt
.
Changing line 10 seems to be trickier, surprisingly. I've come up with this so far:
sed -n 1p choose-line-here.txt |
sed -e '9!b' -e 'N;s/\n.*//;r /dev/stdin' insert-here.txt
The tricky part is, that the r
command inserts the contents of /dev/stdin
, that is, standard input, after the current line. If that is the line which is to be replaced, then I don't see a way to get rid of it without outputting a spare newline. Therefore the trick to start the insertion in the previous line, line 9 in this case.
A simpler solution for changing the target line is possible, if one relies on sed
not counting the freshly read line from stdin:
sed -n 1p choose-line-here.txt |
sed -i -e '9r /dev/stdin' -e '10d' insert-here.txt
Upvotes: 1
Reputation: 1183
I'm not sure where you want your lines to come from and go to, but you could do this:
sed 'NUMq;d' file1 >>file2
replacing NUM
with the number of the line you want from file1 to append to file2.
EDIT
I think this is what you want:
sed -i .bak "10 i\\
`sed 1q\;d file1`
" file2
Upvotes: 1
Reputation: 74655
You can do this using awk:
awk 'NR==1{a=$0}NR==FNR{next}FNR==10{print a}1' file1 file2
NR
keeps a count of the overall line number. This is only equal to 1 for the first line of the first file. The contents of the line is stored in a variable a
.
FNR
keeps a count of the line number of the current file. NR
and FNR
are equal (i.e. we are in file1), next
skips to the next line, which means that for every other line in the first file, nothing happens.
The final block is executed at line 10 of the second file, inserting the value of a
. The 1
at the end is a common shorthand which means that every line of the file is printed.
Testing it out:
$ cat file1
line 1 in file1
line 2 in file1
$ cat file2
line 1 in file2
line 2 in file2
line 3 in file2
line 4 in file2
line 5 in file2
line 6 in file2
line 7 in file2
line 8 in file2
line 9 in file2
line 10 in file2
$ awk 'NR==1{a=$0}NR==FNR{next}FNR==10{print a}1' file1 file2
line 1 in file2
line 2 in file2
line 3 in file2
line 4 in file2
line 5 in file2
line 6 in file2
line 7 in file2
line 8 in file2
line 9 in file2
line 1 in file1
line 10 in file2
To overwrite the original contents of file2, you can redirect the output to a temporary file like awk '...' file1 file2 tmp && mv tmp file2
.
Upvotes: 2