3

I don't have any idea how these files came about to be, but here's what it looks like with ls -lh:

total 8.1G
-rw-r--r--  1 root root 1.6G Apr 13  2022 test_some_data_S6_R2.fastq.gz?
-rw-r--r--  1 root root 1.5G Apr 13  2022 test_some_data_S6_R1.fastq.gz

When I use ls to get the file name to auto-complete, it looks like this -

ls /path/to/file/test_some_data_S6_R2.fastq.gz^M

^M is supposed to be carrier return in DOS, so my best guess, someone might have copied the name from a Windows system and used that for naming the file. There are plenty of methods to replace ^M in the contents of the file, but in my case I want to find files with ^M in its name.

I tried find /path/with/files/ -iname "^M", but no luck. I tried to escape with \, but still no dice. I'm SSHing into a RHEL machine using MobaXTerm, so I tried Windows shortcut CTRL + Q, CTRL + M, but it hides the current working window, and doesn't insert ^M.

5
  • 1
    Your find filter does not have a wildcard, so it cannot work. No idea if it’ll work with a wildcard though.
    – Daniel B
    Feb 6 at 10:33
  • "no idea how these files came to be" – You created or edited a shell script in a text editor that used line endings specific to DOS/Windows, i.e. \r\n aka CRLF This \r in some circumstances is shown as ^M or denoted as CR (these are different representations of the same single-byte character). When reading a script Bash treats sole \n as line terminator, almost any *nix tool does. If there is \r just before, it gets interpreted as any other character. E.g. touch /path/to/file\r will create a file with the name that can be represented as file\r or file^M. (contn'd) Feb 6 at 17:06
  • (contn'd) Use dos2unix or don't use text editors that use CRLF in the first place. Feb 6 at 17:07
  • Another possibility is FTP that translated LF to CRLF. If you happen to transfer your scripts via FTP(S) then compare this answer. Windows-centric text editor is a more probable cause though. Feb 6 at 17:19
  • I did some snooping around, and I think the output filename was copied over from Notepad or something similar (From a windows machine sshing into linux server using MobaXTerm). I guess you're on the money with that one! @KamilMaciorowski Feb 7 at 3:53

2 Answers 2

4

In bash, you can use $'\r' to insert the ^M control character.

find /path/with/files -name '*'$'\r'
  • iname is not needed as the glob expression doesn't contain any letters
  • an asterisk must be included to match the name before the ^M

I was even able to enter ^M directly to a bash command line by the combination of Ctrl + v Ctrl + m. The actual key might depend on bind and its assignment of quoted-insert.

find /path/with/files -name '*^M'
2
  • I have some doubt with the quoting, does the quote before * end after \r? would this be equivalent? "*'$'\r" Feb 6 at 11:41
  • 1
    @KarthikNair: No. There are two things, '*' and $'\r'. You could have tested it with find, your expressions doesn't find the files while the original one does.
    – choroba
    Feb 6 at 12:05
3

Here is a small variation on the method that @choroba posted in their answer.

In a text editor create a small script (called myscript here) that looks like this

#!/bin/bash
find . -name "*^M" -print0 | xargs -0 ls 

The only trick here is that you need to insert the character ^M literally, and there are special tricks for doing so depending on the text editor. In vi or vim it is ctrl-K. In emacs it is ctrl-Q. Use what ever is needed.

Then make the script executable:

chmod 755 myscript

Then execute the script ./myscript. It should just list the files ending with the ^M character. If it does what you want change the xargs -0 ls to xargs -0 rm -f and execute the script again to remove the files

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.