Bash script to Add text to last directory ie., end of path recursively

Hi I am Rupesh from India and I have a pc with Intel i3 10th gen processor and I have installed windows 11 and Arch Linux. I have 10 gb of MP3 files in various sub directories and I want to add text like 128 kbps or 250 kbps to the last directory in the path.

I have mp3 files in the following pattern

music/dir1/dir2/dir3/song1.mp3
music/dir1/dir2/song2.mp3

My requirement is I want to move mp3 files as following

music/dir1/dir2/dir3 128 kbps/song1.mp3
music/dir1/dir2/song2.mp3

Every root directory consists of various sub directories and mp3 files. I just want to add text 128 kbps to the name of last directory in the path.

Previously I have experimented with directories in bash to obtain the last directory in the following way.

$:\ rev source_names.txt > rev.txt
$:\ cut -f1 -d'/'  rev.txt >  temp.txt 
$:\ rev temp.txt > extracted_names.txt

I think that it may be useful in our task.

Here another requirement is dir2 consists of one mp3 with name song2.mp3 and another sub directory and so any text must not be added to the name of dir2 I mean dir2 must not be renamed as dir2 128 kbps.

I have tried bulk rename utility like advanced renamer in windows 11 by adding music folder in it but unfortunately it is renaming all directories present in path ie., dir1 to dir1 128 kbps, dir2 to dir2 128 kbps, dir3 to dir3 128 kbps.

At present I am learning slowly unix and linux concepts and it may take atleast one year for to write a script on my own.

Kindly try to suggest a bash script to accomplish this task.

Regards,
Rupesh.

1 Like

Hi someone from arch linux forums suggested one command and one script. I will check if those works for few files.


tree -fdX music/ | grep -ioP "(?<=name=\").+(?=\"><\/dir)" | sed "s/$/ 128kbs/g"

#!/bin/bash


tree -fdX music/ | grep -ioP "(?<=name=\").+(?=\"><\/dir)" | while read line

do  

mv "$line" "${line} 128kbs"

done

@rupeshforu3 ,

if you are cross posting in a number of forums you can omit doing so here, (read the https://community.unix.com/t/simple-rules-of-the-unix-com-forums/140168 for guidelines), come here for advice if/when all other avenues you have tried have failed to provide a solution.

thks

1 Like

Does the following show the deepest directories?

find music/ -type d -links 2

Spaces in file names can cause problems in losely written shell scripts. Perhaps you can use underscores ("_") instead?

1 Like

Ok from next time I will not repeat. I will post only if I have not found solution in other forums.

Thanks to all of you for your patience.

1 Like

You say you will not repeat, but you've been asking people to write your scripts for you for at least 10 yrs now on many forums:

Especially since you said in 2013 you wanted to "master" unix system

1 Like

@rupeshforu3 Did you read one of the suggested books?
In Unix you can combine simple tools to complex tasks.
Say
find . -type d -links 2
shows the deepest path (true if the file system sticks to the Unix file system conventions),
and if you have a GNU/Linux find (true if find --version says something with GNU).
Then there is still some work to be done.
find does not like if the currently visited directory is renamed. (GNU find does it but complaints.)
The following uses -exec command {} + that runs the command with the collected filename arguments - it takes time to collect the arguments, so find has already left the directories when it invokes the command.)
Then the command is /bin/sh and takes an embedded script; in this case a script name needs to be given before the {} that holds the actual directory name.

find music/ -type d -links 2 -exec /bin/sh -c '
for fn
do
  echo mv "$fn" "${fn}_128_kbps"
done
' mymv.sh {} +

The echo is prefixed for safety: it only prints the mv commands. Remove it, then it runs the mv commands.
A bit less safe (regarding the timing, and regarding newlines in file names) is the following:

find music/ -type d -links 2 |
while IFS= read -r fn
do
  echo mv "$fn" "${fn}_128_kbps"
done

BTW "${fn}_128_kbps" is simply adding the string _128_kbps
You can use a modifier "${fn%_128_kbps}" to do the reverse, i.e. remove a trailing _128_kbps

1 Like

madeingermany, no they didn't and won't read any books. Got banned and deleted from linux.org for stating they'd keep changing the wording on questions until someone answered.

A google for the op's name turns up a ton. Same exact thing every time every where.

@LennyMac , we get the point thks, no need to post more of this.

I think @rupeshforu3 is well aware we are on to their lackadaisical attitude.

tks

Hi at present I am reading the following books

The art of unix programming by Eric raymond

Unix command line by William shots

This topic was automatically closed 300 days after the last reply. New replies are no longer allowed.