I have the following file
titi
tata
toto
tata
If I execute
sed -i "/tat/d" file.txt
It will remove all the lines containing tat
. The command returns:
titi
toto
but I want to remove only the first line that occurs in the file containing tat
:
titi
toto
tata
How can I do that?
To delete a line, we'll use the sed “d” command. Note that you have to declare which line to delete. Otherwise, sed will delete all the lines.
The I flag allows to match a pattern case insensitively. Usually i is used for such purposes, grep -i for example. But i is a command (discussed in append, change, insert chapter) in sed , so /REGEXP/i cannot be used. The substitute command does allow both i and I to be used, but I is recommended for consistency.
Use sed 's insert ( i ) option which will insert the text in the preceding line.
You could make use of two-address form:
sed '0,/tat/{/tat/d;}' inputfile
This would delete the first occurrence of the pattern.
Quoting from info sed
:
A line number of `0' can be used in an address specification like
`0,/REGEXP/' so that `sed' will try to match REGEXP in the first
input line too. In other words, `0,/REGEXP/' is similar to
`1,/REGEXP/', except that if ADDR2 matches the very first line of
input the `0,/REGEXP/' form will consider it to end the range,
whereas the `1,/REGEXP/' form will match the beginning of its
range and hence make the range span up to the _second_ occurrence
of the regular expression.
If you can use awk
, then this makes it:
$ awk '/tata/ && !f{f=1; next} 1' file
titi
toto
tata
To save your result in the current file, do
awk '...' file > tmp_file && mv tmp_file file
Let's activate a flag whenever tata
is matched for the first time and skip the line. From that moment, keep not-skipping these lines.
/tata/
matches lines that contain the string tata
.{f=1; next}
sets flag f
as 1 and then skips the line.!f{}
if the flag f
is set, skip this block.1
, as a True value, performs the default awk action: {print $0}
.awk '!/tata/ || f++' file
||
stands for OR, so this condition is true, and hence prints the line, whenever any of these happens:
tata
is not found in the line.f++
is true. This is the tricky part: first time f is 0 as default, so first f++
will return False and not print the line. From that moment, it will increment from an integer value and will be True.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With