I need help with a script that mv (renames) filenames that are shown with single quotes in ls output or files that require single quotes for file operations. The script will be used to rename all files in a directory. I created a batch of test files using every displayable non-alphanumeric character I can type on my US keyboard (with the exceptions of 'a/b' and 'a'b') to test the script with:
touch 'a~b' 'a`b' 'a!b' 'a@b' 'a#b' 'a$b' 'a%b' 'a^b' 'a&b' 'a*b' 'a(b' 'a)b' 'a-b' 'a_b' 'a+b' 'a=b' 'a{b' 'a}b' 'a[b' 'a]b' 'a|b' 'a\b' 'a:b' 'a;b' 'a"b' 'a<b' 'a>b' 'a,b' 'a.b' 'a?b' 'a b'
So now my test directory contains:
psilo@deb:~/sh$ ls
'a$b' a#b 'a)b' a-b 'a<b' a@b 'a^b' 'a|b'
'a b' a%b 'a*b' a.b 'a=b' 'a[b' a_b a}b
'a!b' 'a&b' a+b a:b 'a>b' 'a\b' 'a`b' a~b
'a"b' 'a(b' a,b 'a;b' 'a?b' a]b a{b filenametweak.sh
In addition, I have the personal preference to tr a space to a . and an underscore to a .
My script is:
#!/bin/bash
for file in *; do echo mv "$file" `echo $file | tr ' ' '.' | tr '_' '.' | tr -cd '\043\045\053-\056\060-\072\077\100-\132\135\141-\173\175\176'` ; done
I am attempting to remove all of the characters from the input stream via the tr command (with -c & -d arguments) other than the ASCII octal values that are shown between the single quotes. This should produce an output with my "problem" ASCII characters removed (those that require the filename to be wrapped in single quotes on the ls output above).
I have included the echo command before the mv "$file" in the script to test the output before pulling the trigger.
However, when the script encounters the '?' or '*' characters in the filename, it produces undesirable output:
psilo@deb:~/sh$ ./filenametweak.sh
mv a$b ab
mv a b a.b
mv a!b ab
mv a"b ab
mv a#b a#b
mv a%b a%b
mv a&b ab
mv a(b ab
mv a)b ab
mv a*b ab.a.b.ab.ab.a#b.a%b.ab.ab.ab.ab.a+b.a,b.a-b.a.b.a:[email protected]]b.ab.a.b.ab.a{b.ab.a}b.a~b
mv a+b a+b
mv a,b a,b
mv a-b a-b
mv a.b a.b
mv a:b a:b
mv a;b ab
mv a<b ab
mv a=b ab
mv a>b ab
mv a?b ab.a.b.ab.ab.a#b.a%b.ab.ab.ab.ab.a+b.a,b.a-b.a.b.a:[email protected]]b.ab.a.b.ab.a{b.ab.a}b.a~b
mv a@b a@b
mv a[b ab
mv a\b ab
mv a]b a]b
mv a^b ab
mv a_b a.b
mv a`b ab
mv a{b a{b
mv a|b ab
mv a}b a}b
mv a~b a~b
mv filenametweak.sh filenametweak.sh
How can I resolve the problem when filenames with * or ? are encountered - OR - how can I achieve my mv rename intent in bash via a different and/or better method?
echo $file
will be subject to globbing - see for example When is double-quoting necessary?for file in *; do echo mv "$file"
`echo "$file" | tr ' ' '.' | tr '_' '.' | tr -cd '\043\045\053-\056\060-\072\077\100-\132\135\141-\173\175\176'
; done