Delete files with string found in file - Linux cli
Asked Answered
P

8

60

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 protected]

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 protected]

Personate answered 25/12, 2010 at 2:53 Comment(0)
M
80

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 protected] | awk '{print "rm "$1}' > doit.sh
vi doit.sh // check for murphy and his law
source doit.sh
Miceli answered 25/12, 2010 at 2:58 Comment(3)
I liked your approach, but for me couldn't do it because I needed a cron job :P So I'm going with this one https://mcmap.net/q/325272/-delete-files-with-string-found-in-file-linux-cliOctroi
How can I count the number of deleted files? piping the command to wc -l doesn't seem to work.Bal
What about a find . -type f ?Yes
E
86

Solution for your command:

grep -l [email protected] * | xargs rm

Or

for file in $(grep -l [email protected] *); do
    rm -i $file;
    #  ^ prompt for delete
done
Elecampane answered 25/12, 2010 at 3:1 Comment(2)
For several files, you can prevent the wildcard adding too many arguments by using grep -l -R --include="*" [email protected] ./ insteadAirliner
sudo grep -lr '/directory/youd/like/to/delete/from/' -e 'text you would like to search' | xargs rm This is what I used. I believe 2grit referenced the '-r' for recursive, which was helpful in my case.Montanez
M
80

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 protected] | awk '{print "rm "$1}' > doit.sh
vi doit.sh // check for murphy and his law
source doit.sh
Miceli answered 25/12, 2010 at 2:58 Comment(3)
I liked your approach, but for me couldn't do it because I needed a cron job :P So I'm going with this one https://mcmap.net/q/325272/-delete-files-with-string-found-in-file-linux-cliOctroi
How can I count the number of deleted files? piping the command to wc -l doesn't seem to work.Bal
What about a find . -type f ?Yes
M
21

You can use find's -exec and -delete, it will only delete the file if the grep command succeeds. Using grep -q so it wouldn't print anything, you can replace the -q with -l to see which files had the string in them.

find . -exec grep -q '[email protected]' '{}' \; -delete
Masterson answered 25/12, 2010 at 3:27 Comment(2)
does find . -exec grep -q '[email protected]' '{}' \; -print show anything?Masterson
yeah, but nothing as expected. find . |grep '[email protected]' at other hand works just fine. I'm on a mac, btw. my answer there solved it for me anyway. ;)Glyceride
G
3

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 protected] | xargs -I {} rm -rf {}

But I rather find by name:

$ find . -iname *something* | xargs -I {} echo {}
Glyceride answered 8/7, 2014 at 23:40 Comment(0)
B
3
rm -f `find . | xargs grep -li [email protected]`

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

Bain answered 6/8, 2017 at 8:43 Comment(0)
S
3

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'
Sandpiper answered 23/11, 2017 at 8:1 Comment(0)
M
2
find . | xargs grep -l [email protected]

how to remove:

rm -f 'find . | xargs grep -l [email protected]'
Manufacturer answered 14/3, 2016 at 7:35 Comment(2)
Welcome to Stack Overflow! While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. - From reviewMoritz
Find works, remove not (centos 6)Worry
F
1

Quick and efficent. Replace find_files_having_this_text with the text you want to search.

grep -Ril 'find_files_having_this_text'  . |  xargs rm
Frontiersman answered 7/7, 2022 at 10:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.