Velvet Star Monitor

Standout celebrity highlights with iconic style.

news

Replace a folder name using a contained file name

Writer Andrew Mclaughlin

I have a thousand or so folders having random names. Every folder has at least one file with avi, mkv,srt or mp4 extension.
I intend to replace the random generated folder name by the first file name (without extension) contained on it. By the way the name of the files use to include () - and other strange characters. The script should, in my opinion:

  1. Go into the folder
  2. Get the first name without extension
  3. Go out of the folder
  4. Rename the folder using the new name
  5. Recursive travel the folders as it may contain other subfolder

The 5th step may be override, though.
As I am a nerd in bash programming, I'd apreciate a hand. Can anyone help?

4

3 Answers

Given

$ tree
.
├── eYRlzR8Ibk
│   ├── Awnluslskl
│   │   └── ö, û, accnts.avi
│   ├── baz
│   └── xyz.mp4
└── wHKEWxFgIt └── foo bar.srt
3 directories, 4 files

then

$ find . -mindepth 1 -depth -type d -execdir sh -c ' for d; do set -- "$d"/*.* [ -e "$1" ] || continue f="${1##*/}" mv -n -- "$d" "${f%.*}" done
' sh {} +

resulting in

$ tree
.
├── foo bar
│   └── foo bar.srt
└── xyz ├── baz ├── ö, û, accnts │   └── ö, û, accnts.avi └── xyz.mp4
3 directories, 4 files
2

The script Copy/paste the script in your text editor
Replace ~/test/testfolders3 in sourcedir variable by your directory name wich contains all the directories with files
Try it without mv $oldname $newname first time to see what should happen.
After editing you could just copy it from your text editor and past it in terminal window.

sourcedir=~/test/testfolders3
cd $sourcedir
files=$(find . -type f)
for f in $files do echo -e "0:Not modified file name:\t $f" bname=$(basename $f) # Get file's name without path to it filewe=$(echo $bname | sed 's/\.[^.]*$//') # Get file's name without extension echo -e "1:Filename without extension:\t $filewe" dir=$(dirname $f) # Get directory name where file is located echo -e "2:Parent file's directory:\t $dir" parfold=$(echo $(dirname $dir) | sed 's/.\///') # Get file's parent directory's parent directory name with stripped `./` preffix echo -e "3:Parent-parent stripped dir:\t $parfold" olddir=$(echo $dir | sed 's@.*/@@') # Get file's parent directory name without path to it (everything before the last `/` slash is stripped) oldname=$sourcedir/$parfold/$olddir # Get current file's parent directory name with full path echo -e "4:Old folder name:\t\t $oldname"; newname=$sourcedir/$parfold/$filewe # Set new file's parrent directory name with full path echo -e "5:New folder name:\t\t $newname" mv $oldname $newname # Renames folders done
find $sourcedir -type f # Shows result

Sorry if it is not fully optimized. I'm not programmer. It's only a compilation of different answers I've found to write it. It took a lot of time, because of I do not do it frequently.

It does not check now if directory exists. So being renamed once by the first moved file's name it will just throw a message like this:

mv: cannot stat '/home/user/test/testfolders3/folders/lkjskd': No such file or directory

The first moved file does not mean the first in alphabetical order.

Here's result of find $sourcedir -type f command execution:

/home/user/test/testfolders3/folders3/file3/file3.mp4
/home/user/test/testfolders3/folders3/file1/file1.avi
/home/user/test/testfolders3/folders3/file2/file2.mkv
/home/user/test/testfolders3/folders3/folders/file3/file3.mp4
/home/user/test/testfolders3/folders3/folders/file1/file1.avi
/home/user/test/testfolders3/folders3/folders/file2/file2.mkv
/home/user/test/testfolders3/folders2/soft/soft.ware
/home/user/test/testfolders3/folders2/soft/file1.avi
/home/user/test/testfolders3/folders2/inter/inter.pol
/home/user/test/testfolders3/folders2/inter/file3.mp4
/home/user/test/testfolders3/folders2/file2/file2.mkv
/home/user/test/testfolders3/folders2/file2/ser.seg
/home/user/test/testfolders3/folders2/folders/file3/file3.mp4
/home/user/test/testfolders3/folders2/folders/file1/file1.avi
/home/user/test/testfolders3/folders2/folders/file2/file2.mkv
/home/user/test/testfolders3/folders/kata/kata.ptx
/home/user/test/testfolders3/folders/kata/file1.avi
/home/user/test/testfolders3/folders/sinaps/sinaps.rtf
/home/user/test/testfolders3/folders/sinaps/file3.mp4
/home/user/test/testfolders3/folders/file2/file2.mkv
/home/user/test/testfolders3/folders/file2/tema.txt
/home/user/test/testfolders3/folders/file2/fan.in

Previous folders' names:

/home/user/test/testfolders3/folders3/kjakd/file2.mkv
/home/user/test/testfolders3/folders3/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders3/folders/kjakd/file2.mkv
/home/user/test/testfolders3/folders3/folders/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders3/folders/lkjskd/file3.mp4
/home/user/test/testfolders3/folders3/lkjskd/file3.mp4
/home/user/test/testfolders3/folders2/kjakd/file2.mkv
/home/user/test/testfolders3/folders2/kjakd/ser.seg
/home/user/test/testfolders3/folders2/jafklsjdkl/soft.ware
/home/user/test/testfolders3/folders2/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders2/folders/kjakd/file2.mkv
/home/user/test/testfolders3/folders2/folders/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders2/folders/lkjskd/file3.mp4
/home/user/test/testfolders3/folders2/lkjskd/inter.pol
/home/user/test/testfolders3/folders2/lkjskd/file3.mp4
/home/user/test/testfolders3/folders/kjakd/file2.mkv
/home/user/test/testfolders3/folders/kjakd/tema.txt
/home/user/test/testfolders3/folders/kjakd/fan.in
/home/user/test/testfolders3/folders/jafklsjdkl/kata.ptx
/home/user/test/testfolders3/folders/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders/lkjskd/sinaps.rtf
/home/user/test/testfolders3/folders/lkjskd/file3.mp4
3

The solution proposed by Steelworker (see above) worked perfectly, fast and smooth. A very clean and simple code. You guys are incredible. Thanks for your time and dedication. Best regards.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy