Home > Mobile >  Trying to create a shell script to rename .jpg extension to the word front of all the directories in
Trying to create a shell script to rename .jpg extension to the word front of all the directories in

Time:12-19

#!/bin/bash

# Iterate through each .jpg file in the current directory
for file in *.jpg; do
  # Rename the file by adding "front" to the beginning of the name
  mv "$file" "front-$file"
done

But after the command I keep getting the error No such file or directory

~/Music$ find . -name '*.jpg' | while read file; do ( mv "$file" "front-$file" ); done
mv: cannot move './dog.jpg' to 'front-./dog.jpg': No such file or directory

CodePudding user response:

The files returned by find . command start with ./ token.

With mv "$file" "front-$file", destination files start with front-./ token.

mv search a directory named front-.. If it's not exists, the command exit with an error code and the associated message.

Replace "front-$file" by "${file%/*}/front-${file##*/}".

Explanations:

  • ${file%/*} remove last right part (part are separated by a /) of the filename
  • ${file##*/} remove all parts from the left, except the last, of the filename

Example:

> file="./the/file/path/file.jpg"
> echo "${file%/*}/front-${file##*/}"
./the/file/path/front-file.jpg

CodePudding user response:

Your current find solution will work for a top/root level directory, and produce the expected output by using basename, something like:

find . -name '*.jpg' | 
  while IFS= read -r file; do 
    echo  mv -- "$file" front-"$(basename -- "$file")"
  done

It gets tricky when you have sub directories, because the *.jpg files will be rename to the desired file name/output but it will also be move to the current directory where you ran/executed the find command.

Consider this directory structure and *.jpg files in them.

tmp/cat.jpg
tmp/fish panda.jpg
dog.jpg

Running your find command against it would result in something like:

mv ./tmp/cat.jpg front-cat.jpg
mv ./tmp/fish panda.jpg front-fish panda.jpg
mv ./dog.jpg front-dog.jpg

A solution with Parameter Expansion for manipulating the path.

find . -name '*.jpg' |
  while IFS= read -r file; do
    file_name=${file##*/}; path_name=${file%/*};
    mv -v -- "$file" "$path_name/front-$file_name"
  done

A solution using -execdir and basename with a for loop.

find . -name '*.jpg' -execdir sh -c '
  for f; do mv -- "$f" front-"$(basename -- "$f")"; done' _ {}  
  • Related