0

Using bash I'm trying to replace all the dots in the name of directories and it's sub-directories with spaces.

Example: the directory dir.1.3 will become dir 1 3

Script I have so far:

#!/bin/bash    
for dir in *\ -\ *; do

      [[ -d "$dir" ]] || continue   # skip if not a directory
      sub="${dir#* - }"
      if [[ ! -e "$sub" ]]; then
        mv "$dir" "$sub"
        mv echo "$(echo "Result: ${dir%.*}" | sed 's/\./ /g').${dir##*.}"

      fi
done
Rick T
  • 357
  • It's not clear why you're looking for files with the pattern * - *, I added an answer using find and pattern *.* (a dot anywhere in the filename). – Freddy Oct 31 '19 at 05:14
  • Are you sure that you want directories with the name that starts with a dot (hidden directories) to start with a space? – v010dya Oct 31 '19 at 05:28

1 Answers1

4

Using find:

find . -mindepth 1 -type d -name "*.*" -exec bash -c '
  for ((i=$#;i>0;i--)); do
    dir=${!i}
    newdir=$(dirname "$dir")/$(basename "$dir" | tr -s "." " ")
    if [ -e "$newdir" ]; then
      echo "skipping \"$dir\", \"$newdir\" already exists" >&2 
    else
      mv "$dir" "$newdir"
    fi
  done
' bash {} +

This finds all directory names recursively with pattern *.* in the current directory skipping the current directory with -mindepth 1. The list of found directories is passed with -exec to a bash script where its arguments are processed in reversed order in the for-loop (subdirectories with a deeper level come first).

The new directory name is created from its dirname and basename. The latter is modified with tr where multiple dots are replaced with one space character (remove option -s if you want to replace multiple dots with multiple spaces). Then print an error message if the new directory name already exists or move it.

Freddy
  • 25,565