我正在从事网站转换工作。从 Web 服务器链接和提供的文件不区分大小写。但是,我已经在 Linux 系统上转储了该站点,并且正在编写脚本来迁移数据。问题是我在页面中的链接字符串与文件系统上的实际单词大小写之间遇到了区分大小写的问题。
例如,页面可能有一个链接,<a href='/subfolder/PageName.asp'>
例如实际文件是/subfolder/pagename.asp
.图像也是如此——<img src='spacer_sm.gif'>
可能是Spacer_Sm.gif
。
所以我的想法是将所有目录和文件名更改为网站下载的小写等效项。我该如何做到这一点(可能有更好的方法吗?)
即使有 unix 命令具有不区分大小写的开关,我使用的是 php,因此并非所有文件系统命令都有区分大小写的选项。
答案1
兹什
zmv -o-i '(**/)(*)' '$1${2:l}'
说明:zmv
根据给定的替换文本重命名与模式匹配的文件。将选项-o-i
传递给底层的-i
每个命令(见下文)。mv
在替换文本中,$1
、$2
等是模式中连续的括号组。**
递归地表示所有(子)*目录。最后一个(/)
不是带括号的组,而是全局限定符,意味着仅匹配目录。${2:l}
转换$2
为小写。
Perl重命名
这里我使用 Debian 和 Ubuntu 附带的 Perl 重命名脚本/usr/bin/prename
(通常也可用rename
)。使用 bash ≥4 或 zsh:
shopt -s globstar # only in bash
rename 's!/([^/]*/?)$!\L/$1!' **/*
与其他外壳:
find . -depth -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +
便携的
递归地:
find . -depth -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;
使用-depth
可确保深度嵌套的目录在其祖先目录之前得到处理。
答案2
我不知道你的unix-flavor是否有rename
.许多 Linux 都有,如果您搜索存储库,它是 perl 软件包的一部分。
find ./ -depth -exec rename -n 'y/[A-Z]/[a-z]/' {} ";"
以上版本带有
rename -n
并不真正执行操作,而只是打印将要执行的操作。你省略了 -n 来真正做到这一点。
答案3
它不适用于以下目录结构:
JKL/
deF/
ABC/DEf
ABC/gHi
ghi/jkL
这是一个有效的示例:
for i in `find | sort -r | sed '$d'`; do \
b=${i%/*}; e=${i##*/}; mv $i $b'/'${e,,}; done
b
有关和vars 的解释e
:
man bash
然后使用以下按键序列:/,,Enterbb
答案4
接受的答案对我不起作用,因为它试图立即更改所有目录。我在 stackexchange 上发现了另一种解决方案,与上面 Gilles 的便携式解决方案非常相似:来自 Baramin -
https://stackoverflow.com/questions/4268591/unix-rename-files-directories-to-uppercase
我把它复制在这里:
find . -depth | \
while read LONG; do
SHORT=$( basename "$LONG" | tr '[:lower:]' '[:upper:]' )
DIR=$( dirname "$LONG" )
if [ "${LONG}" != "${DIR}/${SHORT}" ]; then
mv "${LONG}" "${DIR}/${SHORT}"
fi
done
我将 tr 命令更改为 ie: sed s/cat/dog/g
感谢上面链接中的 Baramin。