将多个子目录移动并重命名到新位置

将多个子目录移动并重命名到新位置

我的目录是这样设置的:

  • dir 1
    • 001
      • 11-20-2001-RT SIMULATION-57976
    • 002
      • 11-20-2001-RT SIMULATION-30560
    • 003
      • 08-24-1998-RT SIMULATION-72882

等等,大约 250 个条目。我的目标是将每个带有字符串的子目录移动RT SIMULATION到另一个目录,即dir 2,但将它们重命名为各自的父目录。所以我正在寻找。

  • dir 2
    • 001(*这应该对应于11-20-2001-RT SIMULATION-57976上面的例子)
    • 002
    • 003

到目前为止,我可以RT SIMULATION使用此代码找到这些目录 for i in $(find /dir1/*/* -name "*RT SIMULATION*" -type d); echo "$i"; done;

现在我需要dir 2根据上面指定的父目录移动并重命名这些目录。有什么帮助或指示吗?

答案1

zsh

autoload -Uz zmv
zmv 'dir 1/(*)/*RT SIMULATION*(#q/)' 'dir 2/$1'

如果你必须使用bash, 并假设一个 GNU 系统,你可以做一些接近的事情:

(
  shopt -s nullglob
  ret=0
  for dir in 'dir 1'/*/*'RT SIMULATION'*; do
    [[ -d $dir && ! -L $dir ]] || continue
    parent=${dir%/*}; parent=${parent##*/}
    mv -iT -- "$dir" "dir 2/$parent" || ret=$?
  done
  exit "$ret"
)

顺便说一句,请参阅为什么循环查找的输出是不好的做法?你的for i in $(find....

答案2

您可以使用 的findperl 版本来rename执行此操作。例如:

首先我要搭建一个测试环境:

$ mkdir /tmp/goldenburrito
$ cd /tmp/goldenburrito
$ mkdir -p 'dir1/001/11-20-2001-RT SIMULATION-5797' \
    'dir1/002/11-20-2001-RT SIMULATION-30560' \
    'dir1/003/08-24-1998-RT SIMULATION-72882'
$ mkdir dir2

然后重命名“RT SIMULATION”子目录:

$ find dir1 -mindepth 2 -maxdepth 2 \
    -type d -name '*RT SIMULATION*' -print0 | 
        rename -0 -n 's:(/\d{3})/.*:$1:; s/^dir1/dir2/'
rename(dir1/003/08-24-1998-RT SIMULATION-72882, dir2/003)
rename(dir1/002/11-20-2001-RT SIMULATION-30560, dir2/002)
rename(dir1/001/11-20-2001-RT SIMULATION-5797, dir2/001)

与 一起使用的-mindepth 2和选项将匹配限制为仅位于 之下的第二级目录。 NUL 分隔的输出通过管道传输到脚本中(可以将文件和目录名称作为命令行参数或来自标准输入)。-maxdepth 2finddir1findrename

对于每个匹配的目录名称,rename脚本首先删除 3 位目录名称后面的所有内容,然后将目录名称开头的“dir1”更改为“dir2”。

请注意,rename-n选项使其成为一次试运行,因此它只会显示它将执行的操作,而不会实际重命名任何目录。当您确认它符合您的要求后,请删除-n,或将其替换为 以获得详细输出。-v

另请注意:perlrename可能被称为file-renameperl-renameprename或简称rename,具体取决于发行版和/或安装方式。例如,在 Debian 上,它被称为rename并且位于rename包中 (so, apt-get install rename)。

不要将其与具有完全不同且不兼容的功能和命令行选项的rename实用程序混淆。util-linux

您可以通过运行来判断您安装的是哪个版本rename -V(如果提到perlFile::Rename,则为 perl 版本)。

Perl 重命名允许您使用任意复杂的 Perl 代码来重命名文件,但最常用于s/search/replace/对文件名执行简单的类似 sed 的操作。

相关内容