Rename files recursivly in specified directories

Hi,

This is what I would like to do.

  1. Find all directories named "ByHost" in a specified directory
  2. Rename all .plist files inside "ByHost" directories

This is the way I have been able to do it so far.

#!/bin/sh
#
# Rename ByHost files
#
# Thomas Berglund, 13.07.08

# Get the Universally Unique Identifier (UUID)
# ioreg commands found at http://www.afp548.com/article.php?story=leopard_byhost_changes
#
# Check if hardware is PPC or early Intel
if [[ `ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-50` == "00000000-0000-1000-8000-" ]]; then
    LEOUUID=`ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c51-62 | awk {'print tolower()'}`

# Check if hardware is new Intel
elif [[ `ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-50` != "00000000-0000-1000-8000-" ]]; then
    LEOUUID=`ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-62`
fi

# Rename .plist files with the right UUID
# I have made a replica of the folder structure for testing purposes
for file in ./System/Library/User\ Template/*/Library/Preferences/ByHost/*.plist ; do

    # Make new file name with the right UUID
    # Note to self: \(.*\) = \1 (pattern group 1, backreference) http://www.grymoire.com/Unix/Regular.html#uh-10
    newName="`echo ${file} | sed "s/\(.*\)\.[^\.]*.plist/\1.${LEOUUID}.plist/"`"

    # Rename files
    mv -v "${file}" "${newName}"
done

When using this method, dotfiles are not included, and there is a file called .GlobalPreferences.UUID.plist in every ByHost folder.

When I try using the find command in the for-loop...

# Rename .plist files with the right UUID
for file in "`find ./System/Library/User\ Template/* -name "*.plist"`" ; do
    # Make new file name with the right UUID
    # Note to self: \(.*\) = \1 (pattern group 1, backreference) http://www.grymoire.com/Unix/Regular.html#uh-10
    newName="`echo ${file} | sed "s/\(.*\)\.[^\.]*.plist/\1.${LEOUUID}.plist/"`"
    #echo "$file"
    # Rename files
    mv -v "${file}" "${newName}"
done

I get this error (I put line breaks in the output to make it readable here in the forum):

mv: rename ./System/Library/User Template/English.lproj/Library/Preferences/ByHost/.GlobalPreferences.0016cb960b0e.plist\n./System/Library/User 
Template/English.lproj/Library/Preferences/ByHost/com.apple.Bluetooth.0016cb960b0e.plist\n./System/Library/User 
Template/no.lproj/Library/Preferences/ByHost/.GlobalPreferences.0016cb960b0e.plist\n./System/Library/User 
Template/no.lproj/Library/Preferences/ByHost/com.apple.Bluetooth.0016cb960b0e.plist\n./System/Library/User 
Template/no.lproj/Library/Preferences/com.apple.Blue.0016cb960b0e.plist to ./System/Library/User 
Template/English.lproj/Library/Preferences/ByHost/.GlobalPreferences.0016cb960b0e.plist ./System/Library/User 
Template/English.lproj/Library/Preferences/ByHost/com.apple.Bluetooth.0016cb960b0e.plist ./System/Library/User 
Template/no.lproj/Library/Preferences/ByHost/.GlobalPreferences.0016cb960b0e.plist ./System/Library/User 
Template/no.lproj/Library/Preferences/ByHost/com.apple.Bluetooth.0016cb960b0e.plist ./System/Library/User 
Template/no.lproj/Library/Preferences/com.apple.Blue.0016cb960b0e.plist: No such file or directory

If I just echo the $file variable, I get this output, and dotfiles are included (the files outside ByHost directories are included too, which is something I would like to avoid):

./System/Library/User Template/English.lproj/Library/Preferences/ByHost/.GlobalPreferences.0016cb960b0e.plist
./System/Library/User Template/English.lproj/Library/Preferences/ByHost/com.apple.Bluetooth.0016cb960b0e.plist
./System/Library/User Template/no.lproj/Library/Preferences/ByHost/.GlobalPreferences.0016cb960b0e.plist
./System/Library/User Template/no.lproj/Library/Preferences/ByHost/com.apple.Bluetooth.0016cb960b0e.plist
./System/Library/User Template/no.lproj/Library/Preferences/com.apple.Blue.0016cb960b0e.plist

When I echo the $file variable in the first script, you can see that it skips dotfiles:

./System/Library/User Template/English.lproj/Library/Preferences/ByHost/com.apple.Bluetooth.0016cb960b0e.plist
./System/Library/User Template/no.lproj/Library/Preferences/ByHost/com.apple.Bluetooth.0016cb960b0e.plist

I have tried adding a second for-loop where I specify the path as ./System/Library/User\ Template/*/Library/Preferences/ByHost/.*.plist. It works, but there must be more efficient way.

Any suggestions?

pseudocode

find /path -name "ByHost" | while read PATH
do
 find "$PATH" -type f  -name "*.plist" | while read FILE
 do
   #do rename
  done
done

Thank you so much! Seems to be working great :slight_smile:

I am pretty new to shell scripting. Ordered a few books from Amazon last week (this and this), but they have not been shipped yet. Looking forward to learn more!