解决方案使用find

解决方案使用find

我想通过添加子目录的名称来重命名每个子目录中的文件。以下是通过添加父文件夹名称来重命名文件, 我试过:

rename  's/(.*)\//$1\/$1_/' */*

但是对于大量的子目录,它不起作用。我有 13,000 个子目录,每个子目录包含大约 300 个文件。我得到

-bash: /usr/bin/rename:  Argument list too long

我试过:

ls | xargs rename 's/(.*)\//$1\/$1_/' */*
find . -maxdepth 1 -type f -print0 | xargs rename 's/(.*)\//$1\/$1_/' */*

两者都给出相同的错误:

-bash: /usr/bin/xargs:  Argument list too long

编辑

xargs -L  rename 's/(.*)\//$1\/$1_/' */*
xargs -L1  rename 's/(.*)\//$1\/$1_/' */*

同样的错误:

-bash: /usr/bin/xargs:  Argument list too long

答案1

作为@egmont 指出,将路径(*/*)作为参数传递给xargs是错误的。此命令从标准输入而不是参数读取文件名,因此发出xargs 没有任何标准输入(问题的编辑部分)都是无用的。

使用ls和的解决方案xargs

检查是否可以仅ls包含所有有问题的路径。

ls */*

如果是,您可以使用 2) 选项的更正版本:

ls */* | xargs rename -n 's/(.*)\//$1\/$1_/'

解决方案使用find

如果调用时出现错误ls,您仍然可以使用find

  1. 此命令有一个-exec与 类似的选项,因此在这种情况下我们根本xargs不需要。xargs
  2. 要模仿的行为ls */*,请使用选项-mindepth 2 -maxdepth 2

3) 选项的更正版本为:

find . -mindepth 2 -maxdepth 2 -type f -exec rename -n 's/(.*)\//$1\/$1_/' {} \;

参数占位符与转义分号 ( {} \;) 一起确保rename每次只针对一个文件运行,类似于xargs -L1。这将防止出现一次运行太多文件的原始问题。

试运行和实际重命名

-n您可以使用我后面提供的选项来检查结果,rename仅列出它将执行的重命名。要实际启动重命名操作,删除-n选项

相关内容