我编写了以下脚本,用于重命名当前目录中的文件,
使用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
在发送之前,是否有更好的方法可以在%s
中转发printf
- es
他们要壳?我对这样做更好的方式不感兴趣,比如shell或者其他东西,我想在这里使用awk
,并且只询问最好的方法将带有空格的文件名传递给shell,不管是什么情况,不只是这个脚本。
答案 0 :(得分:2)
无需使用awk。在BASH 4+中,您可以使用:
echo "${str,,}"
或者其他:
for file in *; do
mv "$file" "${file,,}"
done
答案 1 :(得分:1)
处理嵌套引号总是有点麻烦,但另一种选择是使用这样的东西。我选择使用system
而不是管道sh
:
awk '{lower = tolower($0)} $0 != lower {system("mv '"'"'" $0 "'"'"' '"'"'" lower "'"'"'")}' file
在bash和awk中,默认情况下字符串连接在一起,因此'"'"'"
结束awk单行的第一部分,然后添加单引号(需要用双引号括起来),然后继续使用awk单线程。然后,为了包含$0
的值,需要关闭system
命令中的双引号。看起来有点尴尬,可以说你已经拥有的东西没什么改进,但它确实避免逃避。
使用转义与相同的方法进行比较:
awk '{lower = tolower($0)} $0 != lower {system("mv \"" $0 "\" \"" lower "\"")}' file
顺便说一下,awk脚本的结构是condition { action }
,因此if
语句是多余的。为了避免两次调用lower
,我添加了一个在脚本开头无条件发生的操作,该操作将值存储在变量lower
中。