I have a lot of text files which I am renaming with a specific format. Below I am able to remove whitespaces and make lower case. However, it is not the desired outcome.
How would I be able to format(take out spaces and make lower case) everything up the hyphen and then take only the first white space after the hyphen?
find /temp/ -depth -name "* *" -type f -exec rename 's/ +\././; y/A-Z /a-z_/' {} +
Input Result:
Hello Video - KEEP.txt
Output:
hello_video_-_keep.txt
Desired result:
hello_video_-KEEP.txt
If it was a file I would use:
sed -re 's/^([^-]*)-\s*([^\.]*)/\L\1-\U\2/' -e 's/ /_/g' file
s/^([^-]*)-\s*([^\.]*)/\L\1-\U\2/
converts to lowercase everything from the beginning of the file up to a dash -
. Then it converts to uppercase up to the dot.
s/ /_/g
converts all spaces into underscores _
.
For your given text it returns:
hello_video_-KEEP.txt
If you want to keep the word as it is from the -
up to .
, use \E
to restore the case. Then, we can also get rid of the superfluous _-
by replacing it to just -
(a bit ugly, I know).
$ cat file
Hello Video - KEEP.txt
My File - KeEp.txt
$ sed -re 's/^([^-]*)-\s*([^\.]*)/\L\1\E-\2/' -e 's/ /_/g' -e 's/_-/-/g' file
hello_video-KEEP.txt
my_file-KeEp.txt
As a reminder, these are the ways to change the upper/lower case:
\L
- convert all proceeding characters to lowercase
\U
- convert all proceeding characters to uppercase
\E
- leave all proceeding characters in their current case
How can you mark it work? Loop through the results of the find
command:
while read -r file
do
new_file=$(echo "$file" | sed -re 's/^([^-]*)-\s*([^\.]*)/\L\1\E-\2/' -e 's/ /_/g' -e 's/_-/-/g')
echo "mv '$file' '$new_file'"
done < <(find . -type f ...)
For the given input this will produce this content:
mv './My File - KeEp.txt' './my_file-KeEp.txt'
mv './Hello Video - KEEP.txt' './hello_video-KEEP.txt'
once you are sure it works, just remove the echo
and use mv
alone. Note the quotes are necessary!! Otherwise it won't handle properly the spaces in the file names.
You can use \L
to convert to lowercase:
rename 's/ +\././; y/ /_/; s/(.*?-)/\L$1/'