8

I created a file in Excel and ftp'd the file over to my Linux machine. In the file were a bunch of mkdir commands. Now all of the newly created directories have a carriage return at the end of them. I can find the directories using this command:

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

but when I attempt to remove them using this command:

find . -type d -name *$'\r' | xargs rm-rf

it doesn't work - nothing gets removed. The directories are still there and they still have carriage returns on them.

Can you help me create a command that will remove those pesky '\r's? Thanks.

P.S. I'm using RHEL 5.3

3 Answers 3

11

Linux's rename command makes this easy:

rename $'\r' '' *

This replaces the first and only carriage return ($'\r') by an empty string ('') in all file names in the current directory. Names that don't contain a carriage return are left unchanged (or you can write rename $'\r' '' *$'\r' to only consider files that must be renamed).

If you need to act on files in subdirectories as well:

shopt -s globstar
rename $'\r' '' **/*$'\r'

(Users of Debian, Ubuntu and derivatives: change rename to rename.ul, or change rename $'\r' '' to rename 's/\r//'.)

Alternative, using zsh's zmv function:

zmv $'**/*\r' "${f%?}"
0
3

EDITED: forgot to double escape the \r in the sed line

either of these should work for you

for i in $(find . -type d -name '*\r'); do mv "$i" "$(echo $i | sed -e 's/\\r//g')"; done

find . -type d -name '*\r' -exec mv "{}" "$(echo {} | sed -e 's/\\r//g')" \;

this will find all directories named *$\r under your currently directory

it will then mv(rename) them to the same name minus the \r

4
  • This worked, except I changed '*\r' to *$'\r'. Thanks for the help. I don't know who down-voted this answer - shame on them :) Also, I used the second command you listed.
    – John C
    Jan 9, 2013 at 18:44
  • @FathomSavvy yeah, not sure how a working answer gets down-voted... glad to help though.
    – h3rrmiller
    Jan 9, 2013 at 18:45
  • +1 for a working solution. The downvote is probably from the bash purist brigade for parsing command substitution output, this is deemed a pitfall(mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29). The preferred option is to use a combination of read and find with NUL byte separators see mywiki.wooledge.org/BashFAQ/020
    – iruvar
    Jan 9, 2013 at 18:57
  • @ChandraRavoori that makes a sense, thanks for the tip. I edited and added quotes
    – h3rrmiller
    Jan 9, 2013 at 19:59
0

try this find . -type d -name *$'\r' -exec rm -rf '{}' \;

5
  • 6
    that will remove the file itself not the '\r' from the directory name
    – h3rrmiller
    Jan 9, 2013 at 18:16
  • misunderstood this I attempt to remove them using this command Jan 9, 2013 at 18:45
  • I tried this command. It cut off the first 6 letters of the directory name. I got the error "No such file or directory xxx".
    – John C
    Jan 9, 2013 at 18:50
  • Actually, I think it was a combination of your solution and h3rmiller that made it work.
    – John C
    Jan 9, 2013 at 19:19
  • I think it's a reasonable interpretation that the intention was to remove the files themselves -- from the wording to the sample command being "rm -rf". The comments point out what the Answer should have -- that this answer intends to remove (forcefully, recursively) any directories whose filename ends in a carriage return.
    – Jeff Schaller
    Apr 6, 2020 at 1:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .