Bash - find a keyword in a file and delete its lin

2019-02-12 18:40发布

问题:

This question already has an answer here:

  • Delete lines in a text file that contain a specific string 14 answers

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.

回答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.



回答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.



回答3:

If you want to only delete last line of your example file

sed -i '/[[:space:]]\+domain\.com/d' test.txt