2

There is an answer that is very useful to me in this thread about renaming folders with trailing whitespaces: Remove Leading or Trailing Space(s) in File or Folder Names

What I can't figure out how I can change the following command so that it also changes the names in subfolders.

rename -n 's/ *$//' *

I obviously already tried to check this myself with "rename -h" but I can;t see the solution.

Can someone help me with this?

Thanks a lot in advance,

Chris

3

You may just need to enable the globstar option of the bash shell then use **/* instead of *:

shopt -s globstar
rename -n 's/ *$//' **/*
  • where -n option is dry run.
| improve this answer | |
  • 1
    Although note that this will (at least attempt to) rename the first occurrence of foo wherever it appears in the path (not necessarily in the file name). For the OP's anchored pattern ` *$` that shouldn't be an issue of course. – steeldriver Oct 27 at 11:55
  • Thank you, this answered my question. The only thing to mention is that if there are folders with a space in the end of the name in lower subdirectories as well, that then the command needs to be replicated until all have been renamed. – StackChrisChris Oct 27 at 11:56
  • Hi, @steeldriver, thanks for the comment! My focus here was the globstar option rather than the rename command. – pa4080 Oct 27 at 12:01
  • Thank you again pa4080 and also steeldriver. steeldriver, I just realised what you mentioned in your comment myself. Is there a way to avoid this by using a different OP? I guess the capabilities are limited by the usage of "rename" and next would be to use a small script? – StackChrisChris Oct 27 at 12:06
  • @StackChrisChris, if you want to ping someone by your comment you need to use @ before its nickname. By the way pm-b's answer is also worth. – pa4080 Oct 27 at 12:14
3

If your subfolders as well as files may end with trailing spaces (as discussed in comments), then you will need to process the directory tree depth first1. You can do this with the find command:

find . -depth -name '* ' -execdir rename -n 's/ *$//' {} +

You can replace . (current directory) with a specific starting directory path/to/dir.

The use of -execdir rather than -exec ensures that the replacement is only applied to the file or directory name (rather than the whole path), so it's safe even when the regex pattern isn't anchored to the filename.


1. otherwise it will look OK when testing with -n but will likely fail when applied for real, since it will attempt to rename files in directories whose names have already been changed

| improve this answer | |
  • Thank you @steeldriver ! This is really interesting. – StackChrisChris Oct 27 at 13:10
  • this works super. If I may ask, why are the expressions '{} +' required after the rename command? Is this realted to the find command or to the rename command or to the execdir command? – StackChrisChris Oct 27 at 13:21
  • @StackChrisChris the {} is used by find as a placeholder representing each of the files that it finds. The + at the end tells -execdir (or -exec) to run the command on as many files as possible each time (more efficient) instead of once for each file. See for example What is meaning of {} + in find's -exec command? – steeldriver Oct 27 at 13:25
  • Thank you @steeldriver. Actually the execution of the command with -n gives "'FolderBad1 ' would be renamed to 'FolderBad1'" but without -n gives an error "Can't rename 'FolderBad1 ' to 'FolderBad1': No such file or directory". This is far beyond the question that I initially asked anyways, so just for your information, please :-) – StackChrisChris Oct 27 at 13:30
  • @StackChrisChris I can't reproduce that behavior - you should probably ask a separate question about that, with a testable example – steeldriver Oct 27 at 13:40
1

First, let's look at your use of the rename command. I changed it to match trailing spaces for files with or without an extension:

rename -n 's/( +?)(?=\.[^.]*$|$)//' *

Then to act on all files and files in subfolders, you can use the find command to find all files or directories in a certain path

find . -type f 
find . -type d

and use the -exec subcommand of find to operate on those files or directories. Place the rename command after the exec subcommand. For example:

find . -type f -exec rename -n 's/( +)(?=\.[^.]*$|$)//' {} +
| improve this answer | |
  • Thank you also @pm-b ! I learned something today :-) – StackChrisChris Oct 27 at 13:11

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.