1

Somehow, I seem to have generated files with a carriage return (\r) in the filename:

$ ls -1 tri-rods.tm.dat*
tri-rods.tm.dat
'tri-rods.tm.dat'$'\r'
$ ls tri-rods.tm.dat?
'tri-rods.tm.dat'$'\r'

I tried find with "\r", but it finds nothing:

$ find . -type f -name '*\r'

How can I list/find and remove such files? Adding "?" to the filename works, so I could delete them one by one, but I would prefer a more general way.

Note: I am trying to do this on Windows via Cygwin/git-bash/Windows Subsystem for Linux, so maybe some commands don't work as expected.

KIAaze
  • 767
  • 1
  • 8
  • 18

1 Answers1

3

It finds nothing because the -name test takes a shell glob and globs don't know \r. Assuming your Cygwin shell supports $' ' notation, you could do:

find . -name '*'$'\r''*'

So, to delete, you can do:

find . -name '*'$'\r''*' -delete

Or, if your find doesn't have the -delete action, use:

find . -name '*'$'\r''*' -exec rm {} +

The -regex test might seem like the best option, but unfortunately, none of the regex flavors supported by find know about backslash-letter escapes (also see this answer):

$ find . -regextype findutils-default -regex '.*\r.*'
$ find . -regextype ed -regex '.*\r.*'
$ find . -regextype emacs -regex '.*\r.*'
$ find . -regextype gnu-awk -regex '.*\r.*'
$ find . -regextype grep -regex '.*\r.*'
$ find . -regextype posix-awk -regex '.*\r.*'
$ find . -regextype awk -regex '.*\r.*'
$ find . -regextype posix-basic -regex '.*\r.*'
$ find . -regextype posix-egrep -regex '.*\r.*'
$ find . -regextype egrep -regex '.*\r.*'
$ find . -regextype posix-extended -regex '.*\r.*'
$ find . -regextype posix-minimal-basic -regex '.*\r.*'
$ find . -regextype sed -regex '.*\r.*'

Only the first one, with $'\r' worked for me:

$ find . -name '*'$'\r''*'
./bad?file
terdon
  • 234,489
  • 66
  • 447
  • 667
  • @AdminBee not according to GIlles's answer: [Why can't find -regex match a newline?](https://unix.stackexchange.com/a/119007). And I just tried it and can confirm he's right. – terdon Oct 02 '20 at 09:06
  • Excellent, thanks. Maybe add "find . -name '*'$'\r''*' -delete -print" for completeness to remove the files (verbosily). I tested and it works on all 3: Cygwin, git-bash and WSL. :) – KIAaze Oct 02 '20 at 09:24
  • Also, any more infos on the $' ' notation? I never heard of it before. – KIAaze Oct 02 '20 at 09:26
  • 1
    @KIAaze it's called ["ANSI quoting"](https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html).Note how you actually have it in the output of `ls` shown in your question. And good point, I added a note about deleting, thanks. – terdon Oct 02 '20 at 09:30