Reputation: 4054
I have the following script I wrote, for renaming files in current directory,
using awk
#!/bin/bash
# This script collects filenames from current dir, into list
# and then uses awk to process them, lowering their filenames
[ -f ./tmp.filelist ] && rm tmp.filelist
for file in *
do
echo $file >> tmp.filelist
done
# if file already not all lowercase, make it lowercase
awk '{ if ($0 != tolower($0))
printf("mv \"%s\" \"%s\"\n", $0, tolower($0)) | "sh" }
END { close("sh") }
' tmp.filelist && rm tmp.filelist
Is there some better way of escaping those %s
-es in printf
before sending
them to shell? I am not interested in better way of doing this, like only shell or something, I want to use awk
here, and just asking about best way to pass filenames with spaces to shell, whatever might be the case, not just this script.
Upvotes: 1
Views: 56
Reputation: 74685
Dealing with nested quotes is always a bit of a hassle but another option would be to use something like this. I've chosen to use system
instead of piping to sh
:
awk '{lower = tolower($0)} $0 != lower {system("mv '"'"'" $0 "'"'"' '"'"'" lower "'"'"'")}' file
In bash and awk, strings are concatenated together by default, so the '"'"'"
ends the first part of the awk one-liner, then adds a single quote (which needs to be wrapped in double quotes), then continues with the awk one-liner. In order to then include the value of $0
, the double quotes from the system
command then need to be closed. Looks kind of awkward and is arguably no improvement on what you already had but it does avoid escaping.
Compare that with the same method using escaping:
awk '{lower = tolower($0)} $0 != lower {system("mv \"" $0 "\" \"" lower "\"")}' file
By the way, the structure of awk scripts is condition { action }
so the if
statement is redundant. To avoid calling lower
twice I added an action which happens unconditionally at the start of the script, which stores the value in the variable lower
.
Upvotes: 1
Reputation: 785761
No need to use awk. In BASH 4+ you can use:
echo "${str,,}"
OR else:
for file in *; do
mv "$file" "${file,,}"
done
Upvotes: 2