Linux 如何从“传递文件名”;查找“;至;tr";?
我正在尝试学习几个命令是如何工作的,我想制作一个简单的脚本,将文件名中的大写字母改为小写字母。 我创建了这个脚本:Linux 如何从“传递文件名”;查找“;至;tr";?,linux,shell,Linux,Shell,我正在尝试学习几个命令是如何工作的,我想制作一个简单的脚本,将文件名中的大写字母改为小写字母。 我创建了这个脚本: find * -exec bash -c \ 'echo "${1##*/}" | tr "[:upper:]" "[:lower:]";' _ {} \; 它可以工作,但它只使用echo小写文件名进行写入,而不是更改它们。另一方面,这段代码: find * -exec bash -c \ 'tr "[:upper:]" "[:lower:]";' _ {}
find * -exec bash -c \
'echo "${1##*/}" | tr "[:upper:]" "[:lower:]";' _ {} \;
它可以工作,但它只使用echo小写文件名进行写入,而不是更改它们。另一方面,这段代码:
find * -exec bash -c \
'tr "[:upper:]" "[:lower:]";' _ {} \;
就好像我只会使用:
tr "[:upper:]" "[:lower:]"
因此,我想学习和理解如何传递可以从
中获取的文件名,并使用tr
查找,以及如何处理这些文件名。已经去了手册和谷歌,什么也没找到。嗯tr
就是这么做的;将一个字符集转换为另一个,从上到下。要实际更改文件名,需要使用mv
捕获实际会更改的名称,然后在这些名称上使用mv
;您不能只对每个文件执行mv
,因为这会给您提供类型为mv的错误消息:“blah”和“blah”是同一个文件
As,如果要重命名文件,需要实际调用mv
tr
只是转换字符串(坦率地说,如果您使用的是bash4.0或更高版本,那么没有充分的理由使用它在大写和小写之间转换shell变量,而这正是最新版本)
显示的方法与您已经运行的代码非常类似:
find . -depth -exec bash -c '
for old_name; do
new_name=$(tr "[:upper:]" "[:lower:]" <<<"$old_name")
[[ $old_name = "$new_name" ]] && continue
mv -- "$old_name" "$new_name"
done
' _ {} +;
注意,在第一种情况下,我们使用find-exec{}+
。使用find.
比find*
更可靠,因为它不依赖shell全局搜索;和-exec…\{}+
比-exec…\{} \;因为它将多个名称传递给一个命令,而不是为找到的每个名称启动一个单独的bash副本
while IFS= read -r -d '' old_name; do
new_name=$(tr "[:upper:]" "[:lower:]" <<<"$old_name") # or new_name=${old_name,,}
[[ $old_name = "$new_name" ]] && continue
mv -- "$old_name" "$new_name"
done < <(find . -type f -print0)