Due to a program that wasn't functioning well, I have many files in my home directory starting with a dot and containing strange symbols among which are spaces and asterisks. I want to delete these files, but am having trouble doing so. This problem is similar to Rename file containing spaces and punctuation marks, but much worse. There are way too many files to remove by hand so I will have to use pattern matching.

Most files start with .txt} and contain 18Jun22h (and no files in the directory that I want to keep contain either of these strings). How do I remove all files containing this string given that the files in the directory are certainly not nice unix name? Instead, they contain dots spaces asterisks and brackets and dashes. My initial attempts are failing presumably due to the presence of these symbols in these names.

Any method that deletes them one by one would be completely useless to me due to the quantity of files.

Yes I know it is better to not have files not living up to the unix standard. This is a code I also live by. But a script did not work as it should.

As a second thought, it might be easier to delete all files produced (in the specific directory) between certain times. So alternatively help with this is appreciated.

System: Fedora 27

I had tried ~/*18Jun22h* but thought that the error saying the argument was too long had to do with the *'s in the filenames expanding and doing something strange. Instead it is just because there are too many files matching this pattern (right?). (I did not know that there is a max on the number of files rm can handle).

  • It's difficult to suggest anything without knowing what the files are or if they all contain a specific pattern. – Nasir Riley Jun 25 '18 at 18:07
  • Show us what you tried. – ctrl-alt-delor Jun 25 '18 at 18:09
  • Do the file names contain 18Jun22h or is that in the contents of the file? – Eric Renouf Jun 25 '18 at 18:14
  • is this on a GNU/Linux system, or a different OS? – Jeff Schaller Jun 25 '18 at 18:40

To find files in the home directory (only) that contains at least one space:

find "$HOME" -maxdepth 1 -type f -name '*[ ]*'

... that contain at least one *:

find "$HOME" -maxdepth 1 -type f -name '*[*]*'

... that contain at least [ or ]:

find "$HOME" -maxdepth 1 -type f -name '*[\[\]]*'

... that contain one of any of the above:

find "$HOME" -maxdepth 1 -type f -name '*[ *\[\]]*'

To delete these files, add either -delete to the end of the command, or -exec rm {} +.

On systems where find does not support -maxdepth 1, running from the home directory:

find . -type d ! -name . -prune -o -type f -name '*[ *\[\]]*' -print
| improve this answer | |
  • @JeffSchaller Ah, I missed the bit about the home directory. You're right. – Kusalananda Jun 25 '18 at 18:40
  • -name '*[][* ]*' would probably be more portable. No need for -type d, -prune is harmless on non-directories: find . ! -name . -prune -type f -name '*[][* ]*' – Stéphane Chazelas Jun 26 '18 at 9:00
  • You may need LC_ALL=C as without it, that may fail to match on file names that contain bytes not forming valid characters in the locale's charset. – Stéphane Chazelas Jun 26 '18 at 9:02

Since none of .txt} is special to the shell (there's no opening curly brace), simply:

rm ~/.txt}* ~/*18Jun22h*

or if there are too many, split it up:

rm ~/.txt}*
rm ~/*18Jun22h*
| improve this answer | |
  • These didn't work. The first line (second part) says the argument is too long. The second part actually does not seem to find the files at all. It gives: "rm: cannot remove '/home/name/*18Jun22h*': No such file or directory". Even though with ls -a it is clear that the files containing this do exist (should I add an option to delete hidden files (note the files start with a dot). – Kvothe Jun 26 '18 at 8:35
  • Depends on the shell. rm ~/.txt}* would be a syntax error in zsh (except in sh emulation), fish and rc and derivatives. – Stéphane Chazelas Jun 26 '18 at 8:53

You can come in and out of quotations.

E.g. to remove A file starting with *, then do

rm "*"*

Practice with echo first echo "*"*

| improve this answer | |

You can get the filenames for files which contain a given expression with grep -l, for example grep -l '18Jun22h' *. You can use --null to pass a null character between the files, and send that to xargs:

$ grep -l '18Jun22h' * --null | xargs -0 rm --

I would recommend doing a sanity check first though, as with this 'create and then remove the files' demonstration:

$ for file in 'test file' 'file?name' 'file*name'; do echo foo > "$file"; done; ls -1
test file
$ grep -l foo * --null | xargs -L1 -0 echo
test file
$ grep -l foo * --null | xargs -L1 -0 rm --
| improve this answer | |

Way 1: using ./

rm -f ./'file name' and rm -f ./'file*name'

Way 2: using inode:

Get the inode from ls

ls -i "file name"


find . -inum "numberoofinode" -exec rm {} \;

| improve this answer | |
  • Except for the note from the OP: “Any method that deletes them one by one would be completely useless to me due to the quantity of files.” – Jeff Schaller Jun 25 '18 at 19:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.