Shell脚本从其父文件夹名称重命名多个文件

我有这样的文件结构:

  • 00000010
    • 000000001.file1
    • 000000001.file2
  • 00000020
    • 00000003.file1
    • 00000003.file2
    • 00000003.file3

所以有8位数字的文件夹包含一个或多个文件,名称以8位数字开头。 但是这些文件名是 – 我们说 – 不同步。 所以现在我尝试在bash中recursion地对它们进行重命名以进行存档:

  • 00000010
    • 000000010.file1
    • 000000010.file2
  • 00000020
    • 00000020.file1
    • 00000020.file2
    • 00000020.file3

我的脚本看起来像:

#! /bin/bash find * -maxdepth 1 -name "*" -type d | while read -r dir do rename 's/$dir\/[0-9]{8}/$dir/' * done 

但是这不起作用,并给出错误

全局符号“$ dir”需要在(eval 1)行1处显式包名。

我怎么能写它来根据文件夹名称重命名文件?

谢谢你的帮助!

rename使用"代替'

你应该对$dir里面的文件rename ,所以rename的参数必须是$dir/*而不仅仅是*

既然你想用dir/dir替换dir/8digits ,正则表达式的替换部分应该是$dir\/$dir

通过上述更改,命令如下所示:

 rename "s/$dir\/[0-9]{8}/$dir\/$dir/" $dir/* 

rename实际上是一个Perl脚本。

以下是如何使用bashmv来做到这一点:

 #!/bin/bash for dir in *; do if test -d "$dir"; then ( cd $dir for file in *; do newfile=$dir.${file#*.} mv "$file" "$newfile" done ) fi done 

首先一个脚本来重现你的目录树:

 $ i=1 $ for dir in 000000{1..2}0; do mkdir $dir touch $dir/0000000$i.file{1..3} i=$((i+1)) done $ find . . ./00000010 ./00000010/00000001.file1 ./00000010/00000001.file2 ./00000010/00000001.file3 ./00000020 ./00000020/00000002.file3 ./00000020/00000002.file2 ./00000020/00000002.file1 

现在显示脚本工作:

 $ ../ren.sh $ find . . ./00000010 ./00000010/00000010.file1 ./00000010/00000010.file2 ./00000010/00000010.file3 ./00000020 ./00000020/00000020.file1 ./00000020/00000020.file2 ./00000020/00000020.file3 

首先, *在你的find命令中放错了位置 – 你需要给一个目录开始搜索。 . 是平常的。

其次,perl rename命令中的$dir不会被shell扩展,因为整个字符串都被引用。

第三,你交给你的perl rename命令将扩展到当前工作目录中的所有目录和文件 ,这可能不是你想要的。

@米克尔的回答比我所做的要好得多,但我认为这可能仍然有用。 🙂