如何使用命令行批量重命名大量文件?

如何使用命令行批量重命名大量文件?

我有一个无法解决的问题:我需要使用模式重命名大量文件。我尝试使用,但我总是收到错误。

我有一个文件夹,里面有一个很多文件数。运行后ls -1 | wc -l,显示其中有 160000 个文件。问题是,我希望将这些文件移动到 Windows 系统,但大多数文件都包含类似:和 的字符?,这导致文件在上述基于 Windows 的系统上无法访问。

(作为一个“不解决,而是处理”方法,我尝试在 Windows 系统上启动 LiveCD 并使用实时操作系统移动文件。在 Ubuntu 下,文件在已安装的 NTFS 分区上是可读写的,但当我在 Windows 上重新启动时,它显示该文件在那里,但 Windows 无法以任何方式访问它:重命名、删除或打开。)

我尝试rename 's/\:/_' *在文件夹内运行,但是参数列表太长错误。一些搜索显示,这是因为我有太多文件,然后我到达这里问题是我不知道如何修改命令以满足我的需求,因为我总是遇到各种错误,例如

  • 尝试一下find -name '*:*' | xargs rename : _,它给了xargs:不匹配的单引号;默认情况下,引号对 xargs 来说是特殊的,除非您使用 -0 选项 [\n] 第 1 行(eval 1)处的语法错误,靠近“:” [\n] xargs:重命名:以状态 255 退出;中止
  • 添加-0后将xargs错误消息变为xargs:参数行太长

这些文件是由各种 PHP 脚本生成的存档文件。最好的解决方案是重命名它们它们被移到了 Windows,但如果没有办法,我们也许有办法重命名这些文件尽管它们被移动到 Windows。我使用sambaproftpd来移动文件。

不幸的是,图形软件是不可能的,因为包含文件的服务器就是服务器,只有命令行界面。

答案1

使用 find 的 -exec 应该可以工作,尽管它会递归遍历子目录,而如果任何子目录恰好包含:或 ,它就会失败?

find . -name "*[:?]*" -exec rename 'y/:?/__/' {} +

您收到的错误argument list too long是因为*扩展到目录中的所有 160k 个文件,这超出了系统上的最大参数长度。

$ getconf ARG_MAX
2097152

160k 文件名很容易超过 2MiB。您可以通过一次重命名一个文件来解决此问题

for file in ./*[:?]*; do 
    mv "$file" "${file//[:?]/_}"
done

或者填充一个数组并分块处理它们。块的大小取决于文件名的平均长度和 ARG_MAX 值;或者只需设置一个足够低的值以确保安全,例如 1000:

files=( ./*[:?]* ) n=${#files[@]}
size=1000
for (( i=0; i<n; i+=size )); do
    rename 'y/:?/__/' "${files[@]:i:size}"
done

另请参阅Bash常见问题 30

答案2

我使用它进行批量重命名:vidir。它使用的语法与我们大致相同vi

apt-get install moreutils

进入包含 160k 个文件的目录

cd dir

启动 vidir

vidir

接下来将文件名中的所有 : 替换为例如 -

: % s/:/-/g

对其他奇怪的字符也做同样的事情,例如?

: % s/?/-/g

现在使用 :w 保存文件

vidir 允许在文本编辑器中编辑目录的内容。

http://joeyh.name/code/moreutils/

相关内容