【问题标题】:Shell script to rename multiple files from their parent folders name用于从父文件夹名称重命名多个文件的 Shell 脚本
【发布时间】:2011-06-19 04:09:29
【问题描述】:

我有这样的文件结构:

  • 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 行的包名称。

如何编写它以根据文件夹名称重命名文件?

感谢您的帮助!

【问题讨论】:

  • 请不要cross-post
  • 好的,已经认为这可能不是最好的主意。再也不会发生!对不起。

标签: linux bash shell scripting rename


【解决方案1】:

首先,您的 find 命令中的* 放错了位置——您需要提供一个目录才能开始搜索。 . 是常用的。

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

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

@Mikel 的回答比我正在研究的要好得多,但我认为这可能仍然有用。 :)

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

      【解决方案3】:

      使用" 代替rename 中的'

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2014-08-03
        • 2014-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-14
        • 1970-01-01
        • 2021-11-30
        • 1970-01-01
        相关资源
        最近更新 更多