我的目录是这样设置的:
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
您可以使用 的find
perl 版本来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 2
find
dir1
find
rename
对于每个匹配的目录名称,rename
脚本首先删除 3 位目录名称后面的所有内容,然后将目录名称开头的“dir1”更改为“dir2”。
请注意,rename
该-n
选项使其成为一次试运行,因此它只会显示它将执行的操作,而不会实际重命名任何目录。当您确认它符合您的要求后,请删除-n
,或将其替换为 以获得详细输出。-v
另请注意:perlrename
可能被称为file-rename
、perl-rename
、prename
或简称rename
,具体取决于发行版和/或安装方式。例如,在 Debian 上,它被称为rename
并且位于rename
包中 (so, apt-get install rename
)。
不要将其与具有完全不同且不兼容的功能和命令行选项的rename
实用程序混淆。util-linux
您可以通过运行来判断您安装的是哪个版本rename -V
(如果提到perl
或File::Rename
,则为 perl 版本)。
Perl 重命名允许您使用任意复杂的 Perl 代码来重命名文件,但最常用于s/search/replace/
对文件名执行简单的类似 sed 的操作。