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
  • 787

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
  • 242,166