0

I have been reading this this discussion and this find . -depth -name '* *' \ | while IFS= read -r f ; do mv -i "$f" "$(dirname "$f")/$(basename "$f"|tr ' ' _)" ; done
helps me deleting spaces in files and directories.
Beat Boy becomes Beat_Boy. This is ok.
What I don't get right is how to deal with this:
Beat Boy - Best of becomes Beat_Boy_-_Best_of while I want it to be Beat_Boy-Best_of.
I would appreciate any hint which way to go...

Regards

Barmar
  • 741,623
  • 53
  • 500
  • 612
skeebolt
  • 13
  • 3
  • My hint would be to forget about removing spaces in filenames. I can understand the urge, but in the end, you'll find some elegance in having spaces and hence more natural looking filenames. After all, how readable, legible or elegant is a filename like `Beat_Boy-Best_of`? –  Jun 21 '21 at 18:14
  • Use the `rename` command instead of writing a bash script. – Barmar Jun 21 '21 at 18:45
  • https://stackoverflow.com/questions/13210880/replace-one-substring-for-another-string-in-shell-script – Mauricio Gracia Gutierrez Jun 21 '21 at 20:18

3 Answers3

0

You can add sed to substitute "_-_" with "-"

f="Beat Boy - Best of"

echo $f | tr ' ' _ | sed 's/_-_/-/g'
#Beat_Boy-Best_of

In your case, you would want:

find . -depth -name '* *' | 
    while IFS= read -r f ; do 
        mv -i "$f" "$(dirname "$f")/$(basename "$f" |
            tr ' ' _ |
            sed 's/_-_/-/g')" ; 
    done

Edit

You can also replace tr ' ' _ | sed 's/_-_/-/g' with sed 's/ /_/g ; s/_-_/-/g'.

LC-datascientist
  • 1,960
  • 1
  • 18
  • 32
  • 1
    Yea, if yer gonna use `sed` though, you can just chain both commands into one `echo "Beat Boy - Best of" | sed 's/ /_/g ; s/_-_/-/g'` – Doyousketch2 Jun 21 '21 at 18:47
  • I now have the suggested changes applied and I am testing, as of now, it looks like it does what it is supposed to: `#!/bin/bash find . -depth -name '* *' \ | while IFS= read -r f ; do mv -i "$f" "$(dirname "$f")/$(basename "$f" \ |sed 's/ /_/g ; s/_-_/-/g')" ; done` – skeebolt Jun 22 '21 at 06:43
  • @skeebolt - You can click to accept the answer if it solved your question. It will let others know that the question has been solved. You can also upvote any answers here that you think are useful or can also solve your question. Cheers. – LC-datascientist Jun 22 '21 at 16:11
  • I think LC-datascientist suggestion was the most helpful yet the other answers helped me to understand further dealing with such problems. I will now try to rename only the filenames (not the dirs) from uppercase first letter to lowercase to avoid a mixture of both... – skeebolt Jun 22 '21 at 17:52
0
f="Beat Boy - Best of"
f1=${f// - /-}
f1=${f1// /_}
echo $f1

Beat_Boy-Best_of
Abelisto
  • 14,826
  • 2
  • 33
  • 41
0

This solution just replaces any number of [ ' ' or '-' ] with a single '_'. I assume that's probably what you want.

The find command still only searches for files with spaces in them, but you can change that to suit your needs.


while IFS= read -r f ;
    mv -i "$f" "$(dirname "$f")/$(basename "$f" | sed -re 's/[ -]+/_/g')";
done < <(find . -depth -name '* *')

Full credit: this takes LC-datascientist's solution and replacing the somewhat awkward combination of tr and sed. Even Doyousketch2's comment about sed didn't use s///g option to make it simpler.

Mort
  • 3,379
  • 1
  • 25
  • 40