file name shortening for multiple directories

there was a post previously about this from around 2010
but i was unable to get the suggested scripts there to work.

the following code works for me when it's saved inside the
directory of files whose names i want to shorten, but i would
like to be able to store it in a file with a list of
directories and have it enter into each directory, shorten the
file names in that directory, and then move to the next
directory.

basically enter directory1 and perform the code below,
move to directory2 and do it again, then directory3, etc. etc.

thanks in advance for any help!

rename_seq () 
{   
seq=1   
oldname="$1"   
newname="$2"   
ext="$3"   
while [ -e "$newname$(printf "%02d" $seq).$ext" ]; do     
(( seq ++ ))   
done   
mv "$oldname.$ext" "$newname$(printf "%02d" $seq).$ext" 
}  

ls | while read name; do   
ext="${name##*.}"   
name="${name%.*}"   
newname="${name//[<>=?:;\"*+,|]/_}"   
newname="${newname:0:38}"   
if [ -e "${newname}.$ext" ]; then     
rename_seq "$newname" "$newname" "$ext"   
fi   
if [ -e "${newname}"??".$ext" ]; then     
rename_seq "$name" "$newname" "$ext"   
else     mv "$name.$ext" "$newname.$ext"   
fi 
done

What Operating System and version are you running?
Which Shell is this?

I can't follow your code because it is much too complex.
Idea:

for dir in "directory1" "directory2" "directory3"
do
       cd "${dir}"
       # Rest of the code
done

Or:

cat list_of_directories.txt | while read dir
       cd "${dir}"
       # Rest of the code
done
1 Like

hi! thanks for the fast response.
the first example you gave wouldn't work because i need to shorten the file names in about 1500 different directories. hence i would like a program that can start at the first directory perform the code. move to the next directory, perform the code. move to the next, perform the code, and so on until it gets to the end of the list of directories.
in the second example you gave i'm not sure what "list_of_directories.txt" means or where i would find that. i'm very new to this whole bash thing so if you don't mind giving explanations that would be great!
as far as the code that i gave before (copied from an earlier thread), all it does is takes all of the files in a directory in which it is saved and shortens them to 30 characters and adds a 1 or 2 if some of the files have the same name after they've been shortened. so my end goal is to apply that code to files in many different directories so i don't have to go into each of the 1500 directories i have and run the code. thanks again for any help! hopefully that made sense?

how do you know the 1500 directories. That is the "list_of_dir"

I agree with methyl, your code looks like someone who can program but does not know shell. FORTRAN comes to mind.

Assume the directories you want to mess with are under two main directories. Assume they are /data1 /old_data1. you have many and we will assume those directories lie in a series of subdirectories under the two main ones. I will show you to expand them.
file name matching (expansion) looks like this to find sub directories /directory/*.
This gets everything, all files, including directories

This gets JUST directories, ~/ is shorthand in bash for your login directory.

find /data1/  /old_data1/ -type d > ~/list_of_dir.txt

Now you have a list of directories. Assuming you think your code works correctly

while read dirname
do
  cd $dirname 
  ls | while read name
  do   
    ext="${name##*.}"   
    name="${name%.*}"   
    newname="${name//[<>=?:;\"*+,|]/_}"   
    newname="${newname:0:38}"   
    if [ -e "${newname}.$ext" ]; then     
      rename_seq "$newname" "$newname" "$ext"   
    fi   
    if [ -e "${newname}"??".$ext" ]; then     
       rename_seq "$name" "$newname" "$ext"   
    else     
         mv "$name.$ext" "$newname.$ext"   
    fi 
done  < ~/list_of_dir.txt

I added the code in red. Change the find command to include your directories.
If you already have a list, use that instead.

Just like in other languages, indentation helps readability....

Also modify whatever script created those directory atrocities to start with. Why? UNIX filesystems have limits to the length of filenames and they have length limits to the entire path: [/directorynames..../.../../../../,../loooongfilename]. If you can show us the output of

uname -a

Also a caveat - lots of directories using lots of files use LOTS and LOTS of inodes. Each entry in a directory plus the directory name use an inode. You hit the limit you can't do much with the disk.... You run out of them, you lose. You have to be proactive. Really large directory files are a bad sign.

ls -ld directory_name

will show you how large a directory is. When you have directories in the MB range it is time to think about it long and hard.

1 Like

thank you!!!!! you have made my life about a million times easier. happy monday. :b: