用于从父文件夹名称重命名多个文件的Shell脚本

时间:2011-02-01 10:06:05

标签: linux bash shell scripting rename

我有这样的文件结构:

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

因此,有8位数字的文件夹包含一个或多个文件,名称以8位数字开头。但是这些文件名 - 比方说 - 不同步。所以现在我尝试用bash递归重命名它们来存档:

  • 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行。

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

谢谢你的帮助!

3 个答案:

答案 0 :(得分:5)

使用"代替'

中的rename

您应该对rename内的文件运行$dir,因此rename的参数必须为$dir/*,而不仅仅是*

由于您要将dir/8digits替换为dir/dir,因此正则表达式的替换部分应为$dir\/$dir

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

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

答案 1 :(得分:4)

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

答案 2 :(得分:1)

首先,find命令中的*放错了位置 - 您需要提供一个目录来开始搜索。 .很常见。

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

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

@ Mikel的答案比我的工作要好得多,但我认为这可能仍然有用。 :)