Skip to main content
added 56 characters in body
Source Link

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ddir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children, so that it is safe to rename only the basename element
  • all names may safely contain spaces
  • only one find does the job at lower cost
  • you save dependencies to js

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ddir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children
  • all names may safely contain spaces
  • only one find does the job at lower cost
  • you save dependencies to js

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ddir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children, so that it is safe to rename only the basename element
  • all names may safely contain spaces
  • only one find does the job at lower cost
  • you save dependencies to js
edited body
Source Link

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ddir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children
  • all names may safely contain spaces
  • only one find does the job at lower cost
  • you save dependencies to js

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ddir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children
  • all names may safely contain spaces
  • only one find does the job at lower cost

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ddir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children
  • all names may safely contain spaces
  • only one find does the job at lower cost
  • you save dependencies to js
edited body
Source Link

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ndir"$ddir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children
  • all names may safely contain spaces
  • only one find does the job at lower cost

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ndir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children
  • all names may safely contain spaces
  • only one find does the job at lower cost

Your function were almost conform to your requirements, just missing a lot of quotes around variables and substitutions, that's why it did not resist to space in filenames.

  • variables : "$1" "$2" "$f" etc.
  • substitutions : "$( ... )"

Here is a first low touch review:

deepreplace() {
  if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
  then
      echo "A parameter is missing"
  else
    cd "$1" # quote missing
    vfind="$2" # quote missing
    vreplace="$3" # quote missing
    # Replace the string in file contents
    find . -type f -exec sed -i "s/$vfind/$vreplace/g" {} +
    # Replace the string in directory names
    find . -type d -name "*$vfind*" |
    while read d ; do
      mv "$d" "$(echo "$d" | sed "s/$vfind/$vreplace/g")"
    done
    # Replace the string in file names
    find . -type f -name "*$vfind*" |
    while read f; do
      mv "$f" "$(echo "$f" | sed "s/$vfind/$vreplace/g")"
    done
  fi
}

next improvements:

  • instead of $(echo $v | sed s/x/y/g) use the built-in ${v//x/y}
    example: mv "$f" "${f//$vfind/$vreplace}"
  • you have a problem when the path is to be replaced at more than directory level; that's why you first target directories then files (and not files then directories)
  • it's useless to perform find three times

Here is a pure bash new approach:

    find . | while read p ; do
      ddir="$(dirname "${p//$vfind/$vreplace}")"
      obas="$(basename "$p")"
      nbas="${obas//$vfind/$vreplace}"
      # if object rename
      [[ $obas != $nbas ]] && mv "$ddir/$obas" "$ddir/$nbas"
      # if object is file, edit
      [ -f "$ddir/$nbas" ] && sed -i "s/$vfind/$vreplace/g" "$ddir/$nbas"
    done
  • find natural output order make that directories are always renamed before their children
  • all names may safely contain spaces
  • only one find does the job at lower cost
added 2 characters in body
Source Link
Loading
Source Link
Loading