Delete files with string found in file - linux cli

2019-01-30 04:20发布

I am trying to delete erroneous emails based on finding the email address in the file via Linux CLI.

I can get the files with

find . | xargs grep -l email@domain.com

But I cannot figure out how to delete them from there as the following code doesn't work.

rm -f | xargs find . | xargs grep -l email@domain.com

Thank you for your assistance.

7条回答
Anthone
2楼-- · 2019-01-30 04:21

I liked Martin Beckett's solution but found that file names with spaces could trip it up (like who uses spaces in file names, pfft :D). Also I wanted to review what was matched so I move the matched files to a local folder instead of just deleting them with the 'rm' command:

# Make a folder in the current directory to put the matched files
$ mkdir -p './matched-files'

# Create a script to move files that match the grep
# NOTE: Remove "-name '*.txt'" to allow all file extensions to be searched.
# NOTE: Edit the grep argument 'something' to what you want to search for.

$ find . -name '*.txt' -print0 | xargs -0 grep -al 'something' | awk -F '\n' '{ print "mv \""$0"\" ./matched-files" }' > doit.sh

Or because its possible (in Linux, idk about other OS's) to have newlines in a file name you can use this longer, untested if works better (who puts newlines in filenames? pfft :D), version:

$ find . -name '*.txt' -print0 | xargs -0 grep -alZ 'something' | awk -F '\0' '{ for (x=1; x<NF; x++) print "mv \""$x"\" ./matched-files" }' > doit.sh

# Evaluate the file following the 'source' command as a list of commands executed in the current context:
$ source doit.sh

NOTE: I had issues where grep could not match inside files that had utf-16 encoding. See here for a workaround. In case that website disappears what you do is use grep's -a flag which makes grep treat files as text and use a regex pattern that matches any first-byte in each extended character. For example to match Entité do this:

grep -a 'Entit.e'

and if that doesn't work then try this:

grep -a 'E.n.t.i.t.e'
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-01-30 04:26

@Martin Beckett posted an excellent answer, please follow that guideline

solution for your command :

grep -l email@domain.com * | xargs rm

Or

for file in $(grep -l email@domain.com *); do
    rm -i $file;
    #  ^ prompt for delete
done
查看更多
迷人小祖宗
4楼-- · 2019-01-30 04:30
rm -f `find . | xargs grep -li email@domain.com`

does the job better. Use `...` to run the command to offer the file names containing email.@domain.com (grep -l lists them, -i ignores case) to remove them with rm (-f forcibly / -i interactively).

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-01-30 04:34

For safety I normally pipe the output from find to something like awk and create a batch file with each line being "rm filename"

That way you can check it before actually running it and manually fix any odd edge cases that are difficult to do with a regex

find . | xargs grep -l email@domain.com | awk '{print "rm "$1}' > doit.sh
vi doit.sh // check for murphy and his law
source doit.sh
查看更多
霸刀☆藐视天下
6楼-- · 2019-01-30 04:41

Despite Martin's safe answer, if you've got certainty of what you want to delete, such as in writing a script, I've used this with greater success than any other one-liner suggested before around here:

$ find . | grep -l email@domain.com | xargs -I {} rm -rf {}

But I rather find by name:

$ find . -iname *something* | xargs -I {} echo {}
查看更多
闹够了就滚
7楼-- · 2019-01-30 04:44
find . | xargs grep -l email@domain.com

how to remove:

rm -f 'find . | xargs grep -l email@domain.com'
查看更多
登录 后发表回答