将文件夹和文件名转换为驼峰式大小写
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' *
我有一个名称包含空格的文件夹和文件列表。如何将名称更改为驼峰式?
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' *