In linux, how to delete all files EXCEPT the pattern *.txt?

  • I know how to delete all txt file under current directory by rm *.txt. Does anyone know how to delete all files in current directory EXCEPT txt file?

    As always, test the given answers with a harmless command like `ls` before actually attempting to call `rm`.

    ^ This guy doesn't like to live dangerously.. :)

  • Kevin

    Kevin Correct answer

    7 years ago

    You can use find:

    find . -type f ! -name '*.txt' -delete
    

    Or bash's extended globbing features:

    shopt -s extglob
    rm *.!(txt)
    

    Or in zsh:

    setopt extendedglob
    rm *~*.txt(.)
    #  ||     ^^^ Only plain files
    #  ||^^^^^ files ending in ".txt"
    #  | \Except
    #   \Everything
    

    Some of these may need to be adapted depending on whether you have folders and what you want to do with them.

    Shouldn't `*.!(txt)` be `!(*.txt)`?

    @LauriRanta depends on what's in the folder, which we haven't gotten an answer to. It's fine as is if all the files have extensions, and `rm` would choke if there were folders.

    I've got an issue with the brackets. When I use the globbing style in a bash script, it complains about a syntax error and the parentheses. However doing it from the CLI works.

    `$ find . -type f ! -name "*.txt" | xargs rm`

    @Ntwobike `xargs rm` will give error `rm: missing operand` when all files in the folder have `*.txt` extension (i.e. non-txt files were not found). This makes it impossible to use your variant in `.sh`-files when there are other commands after the failing one.

    @izogfif check this `find . -type f ! -name "*.txt" | xargs -r rm` would work in GNU\xargs. BSD and UNIX xargs command may not have -r you have to check your local `man xargs`

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM