Reputation: 33
I've got a number of folders (80?) with files in them. Some of the filenames have multiple dots (file.name.ext). With the 'find' command being recursive, I'm able to rename the filenames within the folders from uppercase to lowercase:
find . -type f -execdir rename 'y/A-Z/a-z/' {} \;
Where 'find .' indicates to search the current folder. Where 'type f' searches only for files. Where 'execdir' executes the subsequent command on the output.
To do the same (uppercase to lowercase), but for the folders, both of these work:
rename 'y/A-Z/a-z/' *
rename 'y/A-Z/a-z/' ./*
To remove the dots from the foldername, this works:
find . -maxdepth 1 -execdir sed 's/[.]/_/g' {} \;
edit:(actually this is not working for me now)
...
What fails is when I try to recursively remove the dots:
find . -type f -execdir rename 's/\.(?=[^.]*\.)/_/g' '{}' \;
I get the error:
Can't rename ./filename.ext _/filename.ext: No such file or directory
I've also tried to add -printf "%f\n" to remove the leading ./ :
find . -type f -printf "%f\n" -execdir rename 's|[.]|_|g; s|_([^_]*)$|.$1|' {} \;
which outputs the filename followed by the same error
file.name.ext
Can't rename ./file.name.ext _/file.name.ext: No such file or directory
Those commands above were run from the parent folder 'above' the 80 folders that contain the files, with the idea of doing a dryrun (rename -nono) on all the files within the 80 folders at once.
From within one of those 80 folders I can remove the dots from the filename, leaving the dot in the extension unchanged, with:
rename 's/\.(?=[^.]*\.)/_/g'
But I don't want to have to go into each of those many folders to run the command. What will work recursively to delete all dots, leaving the extension dot alone?
Upvotes: 1
Views: 1195
Reputation: 33
I found the answer here: Linux recursively replace periods for all directorys and all but last period for files with underscores
At first I didn't think it answered my specific question, but it actually does.
while IFS= read -rd '' entry; do
entry="${entry#./}" # strip ./
if [[ -d $entry ]]; then
rename 'y/A-Z/a-z/; s/ /_/g; s/\./_/g' "$entry"
else
rename 'y/A-Z/a-z/; s/ /_/g; s/\.(?=.*\.)/_/g' "$entry"
fi
done < <(find . -iname '*' -print0)
Thanks to anubhava .
Upvotes: 1