How can I delete files containing a number '3' or '2' in their filename?

6,162

Solution 1

For the current directory, you can use:

rm -- *[23]*

If you want to restrict it, to match only files where the 2 or 3 must occur between K and .wav:

rm K*[23]*.wav

If you want to make this safer by forcing rm to ask for confirmation for every file, use the -i interactive flag:

rm -i K*[23]*.wav

###Notes

  • the shell glob * matches any number (including zero) of any characters
  • to the shell [some chars] is a character class - anything inside can match
  • -- is recognised by rm as the end of options. This avoids errors if any filenames begin with -; otherwise the filename may be interpreted as an option

If you need to avoid matching 22, 23, 32, 33, you'll need something a little more complex, like αғsнιη's answer.

Solution 2

You can use shell globs:

rm *2* *3*

That will delete all files (not directories) inside the current working directory which get matched by either of the *2* or *3* globs.

In those globs, "* always means "any number (including zero) of any character".

Note however that IIRC Bash's globs don't match hidden files (filename starting with a .) by default.

Solution 3

For the current directory or any other location:

  1. Run this to see what is to be deleted:

    find . -type f -iname "*[32]*.wav" 
    
  2. Then delete with:

    find . -type f -iname "*[32]*.wav" -delete
    

More information:

  • . means current directory, could also be path to location of file, like /path/to/files
  • To prevent find from moving into any directory in the intended target use the option -maxdepth 1, hence:
    • find . -maxdepth 1 -type f -iname "*[32]*.wav" -delete
  • If in the target directory then use:
    • find . -maxdepth 1 -type f -iname "*[32]*.wav" -delete

CAUTION

Never do this find . -delete -type f -iname "*[32]*.wav" else all (your files) will be deleted!

Solution 4

While the given answers also delete files including *23*, *32*, *2*3*, *3*2*, *2* or *3* files patterns + this answer with rm *2* *3* solution will try to delete a file K-0_0_0_0_3_0_1_2.wav two times and second try will failed as it's deleted by *2* matched pattern!.

To avoid these, below is a command which only returns files including 2 or 3 or both in their names only repeated once.

find . -type f -name "*[^0-9][2|3][^0-9]*" #-delete

Or in rm you could use the following instead.

rm -- *[^0-9][23][^0-9]*
Share:
6,162

Related videos on Youtube

I am not Fat
Author by

I am not Fat

Updated on September 18, 2022

Comments

  • I am not Fat
    I am not Fat over 1 year

    I am currently trying to delete some files. The files I want to delete contain the number 3 or 2, either both or one of them.

    How do I delete files containing those numbers?

    The files are named like so:

    K-0_0_1_1_1_1_1_0.wav
    K-0_0_1_1_1_1_1_1.wav
    K-0_1_0_0_0_0_0_0.wav
    K-0_1_0_0_0_0_0_1.wav
    K-0_1_0_0_0_0_1_0.wav
    K-0_0_0_0_0_0_0_2.wav
    K-0_0_0_0_0_0_0_3.wav
    K-0_0_0_0_0_0_1_2.wav
    

    In this list the last three files should be deleted.

  • Byte Commander
    Byte Commander almost 7 years
    Indeed, that character list is even more elegant than two globs :-)
  • Zanna
    Zanna almost 7 years
    @ByteCommander thanks :) but maybe easier to mess up haha. And you demonstrate that rm takes multiple arguments
  • David Foerster
    David Foerster almost 7 years
    Why not simply -delete instead of -exec rm {} \;? No need to invoke rm for every single matched file.
  • Eliah Kagan
    Eliah Kagan almost 7 years
    If for whatever reason one does call rm from find, it's best to use rm -- so the filename argument(s) won't be interpreted as options. Otherwise someone can name a file something like -r and cause trouble... find's -delete action is almost always the best approach, though.
  • Eliah Kagan
    Eliah Kagan almost 7 years
    Well, if rm didn't accept multiple filenames, neither way would work when the shell expands the glob to more than one filename. The main differences between rm -- *[23]* and rm -- *2* *3* are (a) that *2* *3* can give the same filename twice and (b) the order. With the OP's files, echo *[23]* shows K-0_0_0_0_0_0_0_2.wav K-0_0_0_0_0_0_0_3.wav K-0_0_0_0_0_0_1_2.wav while echo *2* *3* shows K-0_0_0_0_0_0_0_2.wav K-0_0_0_0_0_0_1_2.wav K-0_0_0_0_0_0_0_3.wav. With rm this affects deletion order and thus the order errors (or messages due to -v, -i, or -I) are shown.
  • Zanna
    Zanna almost 7 years
    @EliahKagan oh yes of course to the first part :) I didn't realise that it would affect the order of the output though
  • Jérôme
    Jérôme almost 7 years
    +1 for using find. Use it in two steps, first step without -delete, so that you see what you're going to delete next. Also, watch out, if you move -delete before the -type and -iname selectors, you're deleting everything.
  • Zanna
    Zanna almost 7 years
    xargs dies horribly if there are spaces in filenames though...
  • wjandrea
    wjandrea almost 7 years
    I think rm *{2,3}* is equivalent
  • Loreto Gabawa Jr.
    Loreto Gabawa Jr. almost 7 years
    Simple fix for xargs, use find . -type f -name file-pattern -print0 | xargs -0 rm -v. Spaces in files are not a problem for args if you use the -0 to change the deliminator to the null character. If you want a different one, use -d 'char' where char is the delimiter that you want to use. I usually use -exec instead of piping to xargs on find commands myself.
  • αғsнιη
    αғsнιη almost 7 years
    this rm *2* *3* is deleting a file K-0_0_0_0_3_0_1_2.wav two times as example and second try will failed as it's deleted before with matched pattern *2* in rm
  • αғsнιη
    αғsнιη almost 7 years
    This is deleting files also including *23* or *32* files.
  • George Udosen
    George Udosen almost 7 years
    Please explain don't get you @AFSHIN
  • αғsнιη
    αғsнιη almost 7 years
    for example that will delete file K-0_0_0_0_0_0_1_32.wav or K-0_0_0_23_0_0_1_0.wav, see my answer below
  • αғsнιη
    αғsнιη almost 7 years
    + this will delete files with matching *2*3* or *3*2*, like file_22222.wav or file_333333.wav or file_23.wav, ... like other giving answers, please check my answer also
  • αғsнιη
    αғsнιη almost 7 years
    This is true for your answer also.
  • αғsнιη
    αғsнιη almost 7 years
    I'm in bash 4.3
  • Zanna
    Zanna almost 7 years
    sorry it was my bad, my filenames were too diverse - it works on OP's files. But TIL we can use [^.] negation in the shell!