Bash – Rename files based on their parent directory using find/xargs command

bashfilesfindrenameshell-script

I have a directory structure like this:

Project/
  |
  +--Part1/
  |    |
  |    +--audio.mp3
  |
  +--Part2/
  |    |
  |    +--audio.mp3
  |
  +--Part3/
  |    |
  |    +--audio.mp3
...

I want to end up with files called Part1.mp3, Part2.mp3, etc.

Each folder only contains a single file so there is no risk of clobbering files or dealing with multiple files with the same name.

I feel like I could do this with some sort of find/xargs command coupled with cut and mv but I can't figure out how to actually form the command.

Best Answer

These examples work in any POSIX shell and require no external programs.

This stores the Part*.mp3 files at the same level as the Project directory:

(cd Project && for i in Part*/audio.mp3; do echo mv "$i" ../"${i%/*}".mp3; done)

This keeps the Part*.mp3 files in the Project directory:

for i in Project/Part*/audio.mp3; do echo mv "$i" ./"${i%/*}".mp3; done

These solutions use the shell's pattern matching parameter expansion to produce the new filename.

 ${parameter%word}     Remove Smallest Suffix Pattern.  The word is expanded
                       to produce a pattern.  The parameter expansion then
                       results in parameter, with the smallest portion of
                       the suffix matched by the pattern deleted.
Related Question