Linux remove file regexp

How do I remove all files that match a pattern?

When I revert in Mercurial, it leaves several .orig files. I would like to be able to run a command to remove all of them. I have found some sources that say to run:

rm: cannot remove `**/*.orig': No such file or directory 

4 Answers 4

Use the find command (with care!)

I’ve commented out the delete command but once you’re happy with what it’s matching, just remove the # from the line and it should delete all those files.

@FrankBarcenas Yeah — find does everything recursively. If you want to limit how that works, you can play with the -maxdepth or -mindepth arguments.

Definitely leave the -delete at the end of the flags. find . -delete -name ‘*.orig’ will ignore the filter and clobber your whole directory.

@kamal I’d probably still use find but with its -regex or -iregex predicates. Parsing filenames (when you’re piping them around) can be hard to do safely sometimes.

«find» has some very advanced techniques to search through all or current directories and rm files.

find ./ -name ".orig" -exec rm -rf <> \; 

I have removed all files that starts with .nfs000000000 like this

The below is what I would normally do

find ./ -name "*.orig" | xargs rm -r 

It’s a good idea to check what files you’ll be deleting first by checking the xargs . The below will print out the files you’ve found.

If you notice a file that’s been found that you don’t want to delete either tweak your initial find or add a grep -v step, which will omit a match, ie

find ./ -name "*.orig" | grep -v "somefiletokeep.orig" | xargs rm -r 

Источник

Delete multiple files with regex

Try find command with its -regex switch or -iregex (case insensitive), change your regex to .*__[a-zA-z0-9_]*\.(png|jpg|jpeg) and use the -delete option to delete the matched file:

find . -type f -regextype "posix-egrep" -iregex '.*__[a-zA-z0-9_]*\.(png|jpg|jpeg)$' 

You can use other types of -regextype (which is worked) in place of «posix-egrep» like:
«posix-extended» or «posix-awk».

-regex pattern File name matches regular expression pattern. This is a match on the whole path, not a search. For example, to match a file named './fubar3', you can use the regular expression '.*bar.' or '.*b.*3', but not 'f.*r3'. The regular expressions understood by find are by default Emacs Regular Expres‐ sions, but this can be changed with the -regextype option. -iregex pattern Like -regex, but the match is case insensitive. -regextype type Changes the regular expression syntax understood by -regex and -iregex tests which occur later on the command line. Currently-implemented types are emacs (this is the default), posix-awk, posix-basic, posix-egrep and posix-extended. -delete Delete files 

At the end add -delete switch to command to deleting matched files:

find . -type f -regextype "posix-egrep" -iregex '.*__[a-zA-z0-9_]*\.(png|jpg|jpeg)$' -delete 
  • The .* matches everything before __
  • The __ matches double underscores.
  • The [a-zA-z0-9_]* matches all alphanumeric and a single underscore _ characters. The * means this class of characters can be zero length.
  • The \. matches a single dot. To match a dot ( . ) literally you need to escape it within the regular expression using a backslash; without escaping, it matches any single character.
  • In the (png|jpg|jpeg) , pair of parentheses makes it as a group of matches. Will match png or ( | ) jpg or jpeg .
  • The $ anchor, matches the end of string (or file names in this case)
Читайте также:  Astra linux обновить пакеты через терминал

Источник

how to delete files have specific pattern in linux?

Are there any other images in this directory that should not be deleted and if so what are their names?

Test with ls -al [[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]]-image-[[:digit:]]* if that matches what you want to delete, then rm [[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]]-image-[[:digit:]]*

3 Answers 3

Ok I solve it with this pattern

it matches all the file names start with 12345-image- then a number then — symbol and any thing after that

as I found it’s globbing in bash not regex and I found this app really use full

That will match a whole lot more than you think, but only if the filenames start with 12345 . From your comment of «I have just tested this regex 1234-image-. » you indicated that the number of digits was not fixed at five — it this a requirement?.

as I tested it worked. I just want to select files start with specific id then have -image- then a number and an extension at the end

for pic in 12345*.;do rm $pic;done 

for more information on wildcards take a look here

So long as you do NOT have filenames with embedded ‘\n’ character, then the following find and grep will do:

find . -type f | grep '^.*/[[:digit:]]\-image-[[:digit:]]\' 

It will find all files below the current directory and match (1 to 5 digits) followed by «-image-» followed by another (1 to 5 digits). In your case with the following files:

$ ls -1 123-image-99999-small.jpg 12345-image-1-medium.jpg 12345-image-2-medium.png 12345-image-3-large.jpg 12345-image-profile-large.png 12345-image-profile-medium.jpg 12345-image-profile-small.jpg 

The files you request are matched in addition to 123-image-99999-small.jpg , e.g.

$ find . -type f | grep '^.*/[[:digit:]]\-image-[[:digit:]]\' ./123-image-99999-small.jpg ./12345-image-3-large.jpg ./12345-image-2-medium.png ./12345-image-1-medium.jpg 

You can use the above in a command substitution to remove the files, e.g.

$ rm $(find . -type f | grep '^.*/[[:digit:]]\-image-[[:digit:]]\') 
$ l1 12345-image-profile-large.png 12345-image-profile-medium.jpg 12345-image-profile-small.jpg 

If Your find Supports -regextype

Читайте также:  Debian based live linux

If your find supports the regextype allowing you to specify which set of regular expression syntax to use, you can use -regextype grep for grep syntax and use something similar to the above to remove the files with the -execdir option, e.g.

$ find . -type f -regextype grep -regex '^.*/[[:digit:]]\+-image-[[:digit:]]\+.*$' -execdir rm '<>' + 

I do not know whether this is supported by BSD or Solaris, etc. so check before turning it loose in a script. Also note, [[:digit:]]\+ tests for (1 or more) digits and is not limited to 5-digits as shown in your question.

Источник

Remove files by regular expression

I want to keep files whose names match [0-9A-Z]<1,2>_\d_\w+?\.dat , for example, A1_2001_pm23aD.dat , K_1998_12.dat , and remove the rest. However, the ls and rm commands do not support such regexes. How can I do this?

3 Answers 3

shopt -s extglob printf '%s\n' !([[:digit:][:upper:]]?([[:digit:][:upper:]])_[[:digit:]][[:digit:]][[:digit:]][[:digit:]]_+([[:alnum:]]).dat) 

this will print all file/directory names that do not ( ! ) match [[:digit:][:upper:]] followed by zero or one [[:digit:][:upper:]] followed by 4 [[:digit:]] in between _ s and then one or more [[:alnum:]] before the extension .dat .
If you want to search recursively:

shopt -s globstar shopt -s extglob printf '%s\n' **/!([[:digit:][:upper:]]?([[:digit:][:upper:]])_[[:digit:]][[:digit:]][[:digit:]][[:digit:]]_+([[:alnum:]]).dat) 

Alternatively, with gnu find (you can use a regex):

find . -regextype egrep ! -regex '.*/[[:digit:][:upper:]]_[[:digit:]]_[[:alnum:]]+\.dat$' 

There are many ways of doing this. You could use a scripting language that understands regular expressions. For example, in Perl:

perl -le 'unlink(grep(!/[0-9A-Z]_\d_\w+?.dat/,@ARGV))' * 

That will look for all files (not subdirectories) in the current directory, collect those that don’t match the regex and delete them.

You could also do a similar thing with bash, you just need to translate the regex to POSIX ERE:

for f in *; do [[ "$f" =~ [0-9A-Z]_6_[a-zA-Z0-9]+.dat ]] || rm "$f"; done 

Note that in your regex, \w+?.dat will try to match the smallest possible alphanumeric string any character and dat . I don’t see why you would want to use +? here and you probably meant to use \.dat . I am guessing you also probably want to make sure the entire file name matches, so that things like foobarfoobarfoobarA1_2001_pm23aD.datfoobarfooabr are also removed. If so, use one of these instead:

perl -le 'unlink(grep(!/^[0-9A-Z]_\d_\w+\.dat$/,@ARGV))' * 
for f in *; do [[ "$f" =~ ^[0-9A-Z]_3_[a-zA-Z0-9]+.dat$ ]] || rm "$f"; done 

Finally, to also delete directories, you could do:

for f in *; do [[ "$f" =~ ^[0-9A-Z]_3_[a-zA-Z0-9]+.dat$ ]] || rm -rf "$f"; done 

Источник

Оцените статью
Adblock
detector