Bash - find a keyword in a file and delete its line
Solution 1
Use the stream editor, sed:
sed -i ".bak" '/culpa/d' test.txt
The above will delete lines containing culpa in test.txt. It will create a backup of the original (named test.txt.bak) and will modify the original file in-place.
Solution 2
Pipe it to another file, not the same one that you're reading from, and be careful with the useless use of cat
.
grep -v "$KEYWORD" /etc/hosts > newfile
Apart from the fine answer given regarding sed, you can also use Perl and a little improved regex to solve this:
perl -pi.old -e 's/.*\sdomain\.com\s*\n//' file
Notice I'm considering domain.com
will be isolated by space characters (tabs or spaces, and so on), and that nothing but zero or more spaces will appear after it until the newline. Similarly to -i
in sed,
-i.old
in perl sets the $^I
variable, and your original file will receive the changes while a copy will be kept under the old name and a .old
appended.
Solution 3
If you want to only delete last line of your example file
sed -i '/[[:space:]]\+domain\.com/d' test.txt
Comments
-
Roger almost 2 years
I'd like to give a keyword, find the line where this keyword aṕpears in a file and erase the entire line.
This is what I got but it is not working as it should:
KEYWORD='domain.com' cat /etc/hosts | grep -v "$KEYWORD" > /etc/hosts
UPDATE
This is what worked for me:
sed -i_bak -e '/domain\.com/d' /etc/hosts
However, as I had two lines with "domain.com", is there a way to tell sed to erase only the line where the exact keyword "domain.com" appears
This is the original content of /etc/hosts:
127.0.0.1 localhost localhost.localdomain 222.111.22.222 hvn.domain.com 222.111.22.222 domain.com
Here's how it end up after the command
sed -i_bak -e '/domain\.com/d' /etc/hosts
:127.0.0.1 localhost localhost.localdomain
I tried
sed -i_bak -e '/\<namourphoto\.com\.br\>/d' ~/Desktop/hosts
but it didn't work.CONCLUSION
This is the code I came up with (based on the help the fine folks have given me):
D=domain.com DOMAIN=`echo "$D" | sed 's/\./\\\\./g'` sed -i_bak -e "/[\t]$DOMAIN/d" /etc/hosts
Note that:
I am counting that there is always a tab before the domain to be erased
I am automatically escaping the dots of the domain name.
-
duri over 12 yearsPlease also note that dot has special meaning in regexps so
domain.com
will also matchdomainxcom.net
. You should escape the dot. -
Roger over 12 yearsMust I escape dots even when between ''?
-
duri over 12 yearsYes, you do. Try
echo abc | grep 'a.c'
, the output will beabc
. -
Roger over 12 yearsI wrote a code (above) to do escape the dots automatically
-
chad over 12 yearsadd a space to the
[\t]
part, since /etc/hosts is whitespace separated. -
Roger over 12 yearsHow can I write the regex to choose from space or tab?
-
Roger over 12 yearsWhat if I let the option of a space or a tab? (In my case, it's a tab). Would this be right? /[:space:\t]$DOMAIN/d
-
Roger over 12 yearsIs there a way to edit in place with this approach or I always need to make another file in order to edit it?
-
sidyll over 12 years@Roger, I updated the answer.
-
Roger over 12 yearsVery elegant your code, thank you.
-
Roger over 12 yearsMy tests didn't work with the space among -i and .bak. But when I pu -i.bak it did work.
-
sidyll over 12 years@Roger: De nada, e bonito cachorro. Será que essa área verde aí atrás é aqui em SP? :P
-
Roger over 12 yearsorigado, é um Akita. Sim, a paisagem é no Morro do Ouro, em Apiaí; conhece?
-
Adam Johns about 10 yearshow do you do this while discarding the original without making backup? UPDATE: just made the ".bak" quote blank to answer my own question.
-
Luka over 7 yearsin my case keyword is ipaddress with
.
and port:
IS this right?sed -i "/$proxy[^0-9]/d" proxy.txt