谁能向我解释一下这个脚本是如何工作的?

谁能向我解释一下这个脚本是如何工作的?

我正在寻找一个脚本,可以将文件名和目录名改为小写,并将所有空格替换为“-”。我设法在另一个脚本中找到了下面的脚本,但我并不完全了解它的工作原理。如果有人能指导我,我将不胜感激。

find ./* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

答案1

find ./* -depth -type d -exec sh -c ' ... ' {} \;

finds 树中的所有目录 ( -type d) 并为每个目录运行该 shell 片段,并将其$0设置为当前名称。-depth使其首先处理每个目录的内容,最后处理目录本身。 (否则重命名会把事情搞砸。)

t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");

${0%/*}从 中删除最后一个斜杠及其后面的所有内容$0,即保留目录名称。${0##*/}基本上是相反的。 (它们的类型是参数扩展)printf | tr用于将名称的最后部分更改为小写。结果被赋值给t. ($(...)命令替换

[ "$t" = "$0" ] || mv -i "$0" "$t"

测试查看 in 中的新名称t和 in 中的旧名称是否$0相同,如果不是,然后呼叫mv他们。


这里愚蠢的部分是find可以像 一样调用find . -depth ...,不需要文件名通配符 ( find ./*),因为查找文件名就是这样find做的。如果他们使用-execdir而不是-exec,则无需处理文件名的目录部分。使用$0目标文件名的形式有点糟糕,它意味着脚本本身的名称。


您提到重命名文件和目录,并将空格更改为破折号。据我所知,这里的命令两者都没有。find -type d仅捕获目录,您需要用于-type f仅捕获常规文件,或者将其忽略以忽略类型。另外, 中没有任何关于空格的内容tr,但您可以将其更改为,例如tr "[:upper:][:space:]" "[:lower:][-*]"将所有空格更改为破折号。

答案2

我会使用 larry wall rename,它在许多发行版上都可用。包括 Debian,可能还有衍生品。

rename -E 's/-//g' -E 's/(.*)/\L$1/g' *

第一个表达s搜索并替换-为任何内容。第二个表达式搜索并将所有内容替换(.*)为相同的内容$1但转换为小写\L

答案3

您提供的脚本会执行一些操作来提取目录并将其更改为小写。white space到没有变化-

要将空格更改为 - 并将字符串小写,sed 可以正常工作:

sed -e 's/[[:space:]]/-/g' -e 's/\(.*\)/\L\1/'

所以,这个脚本应该可以工作:

find ./* -depth -type d -execdir sh -c '
t=$(printf %s "${1}" | sed -e 's/[[:space:]]/-/g' -e "s/\(.*\)/\L\1/")
[ "$t" = "$1" ] || echo mv -i "$1" "$t"
' sh {} \;

使用-depthand-execdir可以避免提取目录名称。
type d所选元素仅限于目录。

相关内容