I want to learn more so I have tried to script more than just using the terminal. I know rename
and I can rename image files with rename 's/ /_/g' *.jpg
but when I write it in a shell script to point at a directory:
DIRECTORY="/foo/bar"
for imgfile in $(find $DIRECTORY -type f -name \*.jpg); do
echo 'replacing whitespace in' $(basename $imgfile)
rename -f 's/ /_/g' *.jpg
done
it doesn't work and the terminal will take a file (example: 1234 abcd.jpg
) and echo abcd.jpg
. So where am I going wrong?
Spaces in filenames are evil.
I see three problems with the script:
when doing the
for...
loop, you will have two different values when you find a file with space. i.e., if you have the files"file1 1.jpg"
and"file2 2.jpg"
and you do:You'll have
because the shell breaks the argument at spaces. The output of the
$(find ...)
command will beWhich are four words for the command
for
to be assigned at$i
--- by default the shell treats spaces and newlines in the same way when expanding.You can circumvent this changing the IFS char.
Your first line could look like:
you are feeding the for loop with a single file name, so you should say:
otherwise
*.jpg
is expanded in the current directory, and not in$DIRECTORY
(and note the quotes --- given that$imgfile
is going to have spaces in it).even then, if
$DIRECTORY
has some path component with spaces in it, the rename will fail (there will be intermediate directories that do not exist).suggestion (keeping it simple):
doesn't do what you want?
Added: my script (created ages ago, when there was no
rename
in Unix), is this --- it will remove spaces and tab in all files in current dir that have them in the name:Added++: this link I found researching this answer is excellent.
Best way to parse the result from
find
is by null terminate the output with-print0
(You can manage without a loop).