重命名文件而不是目录

重命名文件而不是目录

我想将目录中的所有文件重命名为小写,而不重命名子目录。我知道重命名功能,但它会重命名文件和子目录,这是不需要的。你能帮我吗?

答案1

一切都可以在 perl 表达式中完成。

使用-f常规文件测试,以便仅重命名常规文件(而不是目录)。

这有效:

rename 'y/A-Z/a-z/ if -f;' ./*

(使用./*not 可以*确保没有文件名被解释为选项,即使文件名以破折号 (-) 开头。

答案2

zsh

autoload zmv # best in ~/.zshrc
zmv '*(#q^/)' '${(L)f}'

重命名除目录之外的任何类型的文件。或者:

zmv '*(#q.)' '${(L)f}'

仅重命名常规文件。要还包含隐藏文件,请添加Dglob 限定符。

示例(用于-n试运行):

$ ls -alQF
total 132
drwxr-xr-x   3 stephane stephane   4096 Oct 27 09:11 "."/
drwxr-xr-x 533 stephane stephane 122880 Oct 27 09:11 ".."/
drwxr-xr-x   2 stephane stephane   4096 Oct 27 09:07 "DIR"/
lrwxrwxrwx   1 stephane stephane      3 Oct 27 09:07 "DIR-LINK" -> "DIR"/
prw-r--r--   1 stephane stephane      0 Oct 27 09:07 "FIFO"|
-rw-r--r--   1 stephane stephane      0 Oct 27 09:11 ".HIDDEN FILE"
-rw-r--r--   1 stephane stephane      0 Oct 27 09:07 "HOLIDAYS IN МОСВА\nRED SQUARE.JPG"
lrwxrwxrwx   1 stephane stephane     23 Oct 27 09:08 "MY-RÉSUMÉ.PDF" -> "STÉPHANE'S RÉSUMÉ.PDF"
-rw-r--r--   1 stephane stephane      0 Oct 27 09:07 "--READ-ME--.TXT"
srwxr-xr-x   1 stephane stephane      0 Oct 27 09:09 "SOCKET"=
-rw-r--r--   1 stephane stephane      0 Oct 27 09:07 "STÉPHANE'S RÉSUMÉ.PDF"

$ zmv -n '*(#q^/)' '${(L)f}'
mv -- DIR-LINK dir-link
mv -- FIFO fifo
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- MY-RÉSUMÉ.PDF my-résumé.pdf
mv -- --READ-ME--.TXT --read-me--.txt
mv -- SOCKET socket
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf

$ zmv -n '*(#q.)' '${(L)f}'
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- --READ-ME--.TXT --read-me--.txt
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf

$ zmv -n '*(#qD.)' '${(L)f}'
mv -- .HIDDEN\ FILE .hidden\ file
mv -- HOLIDAYS\ IN\ МОСВА$'\n'RED\ SQUARE.JPG holidays\ in\ мосва$'\n'red\ square.jpg
mv -- --READ-ME--.TXT --read-me--.txt
mv -- STÉPHANE\'S\ RÉSUMÉ.PDF stéphane\'s\ résumé.pdf

看看其中一些如何破坏一些符号链接。

答案3

可以通过将 var 排版为小写来完成转换为小写。

编辑:将解决方案替换find为 的解决方案for

我首先尝试使用 的解决方案find,希望仅使用-type f.
这似乎工作得很好:
我使用过-maxdepth 1,所以我没有更改其他文件夹中的任何内容(当目录名称为大写时,这会稍微困难一些)。
这导致了

typeset -l smallfile
echo "Find solution looks OK but read more..."
find .-maxdepth 1 -type f| while read file; do
        smallfile="${file}"
        mv "${file}" "${smallfile}"
done

我认为这种结构可以正确处理带有空格的文件名,我用“带有空格的文件”等文件名进行了测试。 @Chazelas 正确地评论说,该解决方案因文件名以空格结尾而失败(“太糟糕了”)。另一条评论解释了如何修复find- 命令:(find ... -print0 | while IFS= read -rd '' filefind必须支持print0,主要是bashzsh)。
由于我已经在使用循环,因此我也可以使用test查看当前项目(由 给出*)是否是常规文件。
我找到了一个带有简单 for 循环的解决方案,并在此处展示了它,包括我的测试代码。

#!/bin/bash
clear
rm -rf testfiles 2>/dev/null
mkdir -p testfiles/SomeDir #2>/dev/null
mkdir testfiles/"Crazy Dir" 2>/dev/null
touch testfiles/Aha testfiles/"File with Spaces" testfiles/"End with space "
ls -lQ testfiles
echo ===================
typeset -l smallfile
for file in testfiles/* # Stack's formatting thinks /* starts comment, so I close that here: */
do
   if [ -f "${file}" ]; then
        smallfile="${file}"
        # echo mv "${file}" "${smallfile}"
        mv "${file}" "${smallfile}"
   fi
done
echo ===================
ls -lQ  testfiles

对于当前目录,testdir/从 for 循环中删除。

答案4

这个 oneliner 将解决这个问题:

find path-to-search -depth -type f -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

呀!

相关内容