Issue
I want to remove all special characters with a space except the dot before the extension. Let's take this file as an example, since I have tons of them.
FRD - 2023.04.12 - (mj)_Text and other chars[ ].txt
Desired output:
FRD 2023 04 12 mj Text and other chars.txt
I've written a series of commands that allow me to do just that:
Remove all dots except the extension one:
rename -v 's/\.(?!(avi|mkv|mp4|mov|wmv|jpg|jpeg|png|txt))/ /g' *
Result:
FRD - 2023 04 12 - (mj)_Text and other chars[ ].txt
Remove all other characters except the extension dot:
rename -v 's/(([^a-zA-Z\d\s])|(-)|(:))(?!(avi|mkv|mp4|mov|wmv|iso|jpg|jpeg|png|txt))/ /gi' *
Result:
FRD 2023 04 12 mj Text and other chars .txt
Reduce multiple spaces to a single one:
rename -v 's/\s{1,10}/ /g' *
Result:
FRD 2023 04 12 mj Text and other chars .txt
And because there were characters just before the extension, remove this space:
rename -v 's/(\s+)(?=(\.))//g' *
Result:
FRD 2023 04 12 mj Text and other chars.txt
Now I put all these commands in a script with a for loop. Here is the script:
#!/bin/bash
for f in ./*; do
rename -v 's/\.(?!(avi|mkv|mp4|mov|wmv|mpg|iso|flv|jpg|jpeg|png|txt))/ /gi' *
rename -v 's/(([^a-zA-Z\d\s])|(:))(?!(avi|mkv|mp4|mov|wmv|mpg|iso|flv|jpg|jpeg|png|txt))/ /gi' *
rename -v 's/\s{1,10}/ /g' *
rename -v 's/(\s+)(?=(\.))//g' *
done
Here's how it looks using the script:
FRD 2023 04 12 Mj Text and Other Chars Txt
Why, if all these commands work one after the other, do they not give the same result in a script? What is the problem is?
Solution
When you run the commands individually, you pass *
to each command, which expands to the current file list. In the script you have a for
loop, which executes the commands on all files, and repeats for the amount of files. This means that if you have 17 files in the directory, each command will run 17 times on all files, which is not what you want.
Simply remove the for
loop, and keep the commands as they are;
#!/bin/bash
rename -v '...x...' *
rename -v '...y...' *
# and so on..
(of course, replace '...x...'
/'...y...'
with the actual patterns)
Answered By - micromoses Answer Checked By - Gilberto Lyons (WPSolving Admin)