Find and replace text in a file between range of lines using sed
You can use sed addresses:
sed '19,33s/google/facebook/g' file
This will run the substitution on lines between and including 19 and 33.
The form of a sed command is as follows:
[address[,address]]function[arguments]
Where 19,33
is the addreses,s
ubstitute is function
and g
lobal is the argument
How to perform sed replacement on range of lines?
You were close
sed -i '200,220 s/1 2 3 4 5 /replacement numbers/' file
in 200-220 range this will replace '1 2 3 4 5 ' with other stuff only once (per line). If more replacements needed than added g here ...numbers/g' file and so on
Replace text between two lines with contents of a file stored in a variable in sed
This might work for you (GNU sed):
sed '/blue/,/gray/!b;//!d;/blue/r file2' file1
For the range of lines between blue
and gray
, delete lines that do not match either the first or the last lines in the range and read the lines to insert before the last line of the range.
EDIT:
The first sed command /blue/,/grey/!b
matches a range of lines i.e. the lines that range between a line containing blue
upto and including a line containing gray
. The !b
part means if the lines are not in that range then break out of the sed commands i.e. do not do any further sed processing for these lines, just print as normal.
The sed commands following will only affect those lines that are in the range between blue
and gray
.
The second command //!d
means: delete those lines that do not match either the start/end of the range i.e. blue
or gray
. The //
uses the regexp from a previous /.../
command. N.B. a delete command terminates any further sed processing for that line.
The sed commands following will only affect lines that containing either blue
or gray
.
The third command matches a line containing blue
and reads in lines from file2.
N.B. the lines containing blue
and grey
are processed by sed naturally and printed before the next line is read into the pattern space as are the lines not between blue
and gray
.
An alternative:
sed '/blue/,/gray/!b;//!d;/gray/e cat file2' file1
And another:
sed -ne '/blue/{p;r file2' -e ':a;n;/gray/!ba};p' file1
How to replace a range of numbers from a range of strings with sed
You can do everything in one go with a slightly more complex regex.
sed 's/lcl|NC_.*_cds_\(XP_[0-9.]*\)_.*/\1/' cds.fa > cds4.fa
The backslashed parentheses create a capturing group, and \1
in the replacement recalls the first captured group (\2
for the second, etc, if you have more than one). The regex inside the group looks for XP_
followed by digits and dots, and the expression after matches the rest of the line from the next uderscore on.
In other words, this basically says "replace the whole line with just the part we care about".
By the by, there is no reason to backslash underscores anywhere, and the /g
option to the s
command only makes sense when you want to replace multiple occurrences on the same input line.
Using sed to replace value in lines, between specific line number range in a file
Just add the line numbers in commas
sed "10,13s/Frame=[[:digit:]]\+/Frame=1/" data.txt
how to use sed to replace the specific line/lines in a file with the contents from another file
To replace a range of lines with entire contents of another file:
sed -e '15r file2' -e '15,18d' file1
To replace a single line with entire contents of another file:
sed -e '2{r file2' -e 'd}' file1
If you don't know whether file2
ends in newline or not, you can use the below trick (see What does this mean in Linux sed '$a\' a.txt):
sed '$ a\' file2 | sed -e '3{r /dev/stdin' -e 'd}' file1
The main trick is to use r
command to add contents from the other file for the starting line address. And then delete the line(s) to be replaced. The -e
option is needed because everything after r
will be treated as filename.
Note that these have been tested with GNU sed
, I'm not sure if it will vary for other implementations.
See my github repo for more examples, such as matching lines based on regex instead of line numbers.
sed read entire lines from one file and replace lines in another file
If you have GNU sed which supports s///e
, you can use the e
to call head -n3 file1
I think (w/o yet testing):
sed '2d;3s/.*/head -n3 file1/e' file2
I'll go verify...
Replace a pattern range line by line with sed
The closest code I have gotten is this, but I have to rewrite the
entire range and it is not affordable:sed -e '/==OPEN==/ {:loop; N; /==CLOSE==/! b loop; /id: class8/ {s/.*/NEEDS REWRITE/}}' /example
That's actually not bad.
If I tell it to rewrite the beginning (^), it rewrites only the first
line of the range, I think it is because it considers the entire
pattern as one line.
Yes, with POSIX sed
, and with GNU sed
by default, the ^
matches the beginning of the pattern space only. However, you can match the newlines themselves:
sed -e '/==OPEN==/ {:loop; N; /==CLOSE==/! b loop; /id: class8/ {s,\(^\|\n\),\1// ,g}}' \
/example
Note in particular:
- The text being replaced is expressed as the group
\(^\|\n\)
, meaning either the zero-length substring at the beginning of the pattern space or a newline, which is captured as a group. - The matched text is echoed back into the replacement via
\1
. That has no visible effect when it is the^
alternative that matches, but it avoids eliminating newlines when the other alternative matches. - The comma (
,
) is used as pattern delimiter, so that the slashes (/
) in the replacement text don't need to be escaped. - The
g
flag is used to cause all appearances of the pattern to be replaced, not just the first.
If you are willing to rely on GNU extensions, then you can do it a bit more simply:
sed -e '/==OPEN==/ {:loop; N; /==CLOSE==/! b loop; /id: class8/ {s,^,// ,gm}}' \
/example
With GNU sed
, the m
flag in the s
command causes ^
to match both at the beginning of the pattern space and immediately after each newline within. This flag is not specified by POSIX.
Replace block of text inside a file using the contents of another file using sed
So I guess this should be a reasonably short way of doing it to replace text between foo
and bar
lines with content of file file_content
:
sed -e '/^foo$/,/^bar$/{/^bar$/{x;r content_file
D};d}' file
For range of lines matching ^foo$
and ^bar$
. If line matches ^bar$
swap (empty) hold space into pattern space, read and append content of content_file
, then delete pattern space up to first newline and start next cycle with the reminder of the pattern space. For all other lines in that range... just drop the line (delete patter space and move to the next line of input).
Otherwise to the result of your question... any string enclosed in single quotes is taken literally by shell and without any expansion (also of variables) taking place. '${content}'
means literally ${content}
and that is also part of the argument passed to sed
, whereas double quote text ("${content}"
) would still see shell expand variable to what its value before becoming part of the sed
arguments. Since that could still see content tripping up sed
, I would opt for the r
method for being more generic / robust.
EDIT: Edit keeping the start and end lines in (since I've misread the question):
sed -e '/^foo$/,/^bar$/{/^foo$/{r content_file
p};/^bar$/!d}' file
This time for range between matched of ^foo$
and ^bar$
... for opening line matching ^foo$
we it r
eads content from content_file
appending it to pattern space and then p
rints it (because of d
elete that follow). Then for all line in the range not matching the closing line pattern ^bar$
it just drops it and moves on.
Related Topics
Linux Keyboard Event Capturing /Dev/Inputx
How Does Copy_From_User from the Linux Kernel Work Internally
Why Do the Md5 Hashes of Two Tarballs of the Same File Differ
What Is the Safest Way to Run an Executable on Linux
Linux 3/1 Virtual Address Split
Run a Persistent Process via Ssh
Could Not Load Shared Library Symbols for Linux-Vdso.So.1. While Debugging
How to Return Exit Code 0 from a Failed Command
Loading Linux Text File into Excel Using Vba
How to Disable Socket Creation for a Linux Process, for Sandboxing
How to Save the Output of This Awk Command to File
Possible Values for 'Uname -M'
Delete All Files Except the Newest 3 in Bash Script