将文件夹和文件名转换为驼峰式大小写

Convert folder and file names to camel case

我有一个名称包含空格的文件夹和文件列表。如何将名称更改为驼峰式?

for oldname in *
do
  newname=`echo $oldname | sed -e 's/ /_/g'`
  if [ "$newname" = "$oldname" ]
  then
    continue
  fi
  if [ -e "$newname" ]
  then
    echo Skipping "$oldname", because "$newname" exists
  else
    mv "$oldname" "$newname"
  fi
done 

我找到了这个,但是它将空格更改为下划线。

试试这个 Shellcheck-clean Bash 代码:

#! /bin/bash -p

lowers=abcdefghijklmnopqrstuvwxyz
uppers=ABCDEFGHIJKLMNOPQRSTUVWXYZ

for oldname in *; do
    [[ $oldname == *[[:space:]]* ]] || continue
    read -r -d '' -a parts <<<"$oldname"
    newname=''
    for p in "${parts[@]}"; do
        char1=${p:0:1}
        if [[ $lowers == *"$char1"* ]]; then
            tmp=${lowers%"$char1"*}
            uchar1=${uppers:${#tmp}:1}
            newname+=${uchar1}${p:1}
        else
            newname+=$p
        fi
    done
    if [[ -e $newname ]]; then
        printf "Skipping '%s', because '%s' exists\n" "$oldname" "$newname" >&2
    else
        echo mv -v -- "$oldname" "$newname"
    fi
done
  • 该代码旨在与(现在古老的)Bash 3 一起使用,因为我的理解是这仍然是 macOS 上标准 Bash 的当前版本。将文件名部分的首字母大写的代码比 Bash 的更高版本(具有 built-in 大小写转换机制)的代码复杂得多。有关在 Bash 的各种版本中以各种方式更改大小写的信息,请参阅 How to convert a string to lower case in Bash?
  • 该代码仅打印 mv 命令,即 运行。删除 echo 使其实际执行 mv.
  • 请参阅对 Why is printf better than echo? 的已接受且优秀的回答,以了解为什么我将 echo 替换为 printf 来表示“跳过”消息。

为了比较,这是Bash 4+代码:

#! /bin/bash -p

for oldname in *; do
    [[ $oldname == *[[:space:]]* ]] || continue
    read -r -d '' -a parts <<<"$oldname"
    newname=''
    for p in "${parts[@]}"; do
        newname+=${p^}
    done

    if [[ -e $newname ]]; then
        printf "Skipping '%s', because '%s' exists\n" "$oldname" "$newname" >&2
    else
        echo mv -v -- "$oldname" "$newname"
    fi
done

您可以使用正则表达式 aptitude 来处理大小写转换,关于您当前的本地排序规则(LC_ALL,请使用 locale 命令检查)。

如果您的文件名的“单词”用 space 分隔并且都是小写 ,您可以使用像这样的简单 shell 脚本:

#!/bin/sh
while read -r FILENAME ; do
  NEWNAME="`echo \"${FILENAME}\" | sed 's/  *\([^ ]\)/\u/g'`"
  if [ ! "${NEWNAME}" ] ; then
    NEWNAME="${FILENAME}";
  fi
  if [ "${FILENAME}" = "${NEWNAME}" ]; then
    printf "No change : %s\n" "${FILENAME}" >&2;
  else
    if [ -e "${NEWNAME}" ] ; then
      printf "Already changed : %s => %s\n" "${FILENAME}" "${NEWNAME}" >&2;
    else
      echo "mv \"${FILENAME}\" \"${NEWNAME}\"";
    fi
  fi
done

删除 echo "mv \"${FILENAME}\" \"${NEWNAME}\""; 上的 echo 以执行 mv。

请注意,它应该可以很好地处理重音字母或任何具有低位和高位代码的 unicode 字母。

该脚本从 stdin 获取文件列表进行操作,因此要“按原样”使用它,您可以使用类似于以下示例的内容:

  • find . -type 'f' | theScript.sh

    对于整个文件树。 对于文件夹,您必须单独操作它们。列出它们并按降序排列。

  • ls -1 | theScript.sh

    对于当前文件夹中的文件

如果您的文件可能在开头全部或部分大写 并且您希望将它们完全强制为驼峰式大小写,您可以更改行:

  NEWNAME="`echo \"${FILENAME}\" | sed 's/  *\([^ ]\)/\u/g'`"

有:

  NEWNAME="\`echo \"${FILENAME}\" | sed 's/\(.*\)/\l/;s/  *\([^ ]\)/\u/g'\`"

如果您安装了 rename,那么您需要做的就是:

rename 's/ /_/g' *