【问题标题】:Linux rename files as dirnameLinux 将文件重命名为 dirname
【发布时间】:2016-08-01 01:03:30
【问题描述】:

我有很多这样的文件:

./1/wwuhw.mp3
./2/nweiewe.mp3
./3/iwqjoiw.mp3
./4/ncionw.MP3
./5/joiwqfm.wmv
./6/jqoifiew.WMV

如何在 Linux Bash 中像这样重命名它们:

./1/1.mp3
./2/2.mp3
./3/3.mp3
./4/4.MP3
./5/5.wmv
./6/6.WMV

【问题讨论】:

  • 您好,欢迎来到堆栈溢出。但是,您的问题与 Stack Overflow 无关,因为它与特定的编程问题无关。请查看help center。如果您能够修改您的问题以保持主题,请查看How to Askminimal reproducible example,了解如何最好地做到这一点。否则,您可能需要查看 Unix & LinuxSuper User 以获取有关文件操作和 linux bash 系统的信息。
  • 这个问题是关于脚本的,在这里很好。

标签: linux bash find rename


【解决方案1】:

for 循环方法,如其他一些答案中所述,对于大多数需要将目录中的 每个 文件重命名为第一个父目录名称的情况来说就足够了并且效果很好.我的特殊情况需要更多粒度,我只想重命名目录中文件的 子集 并断言操作数实际上是一个实际的 文件,而不是空目录、符号链接等。使用find 可以完全实现您想要的,此外还可以对文件输入和输出应用过滤和处理。

#####################################
# Same effect as using a `for` loop #
#####################################
#
#   -mindepth 2 : ensures that the file has a parent directory.
#   -type f : ensures that we are working with a `regular file` (not directory, symlink, etc.).

find . -mindepth 2 -type f -exec bash -c 'file="{}"; dir="$(dirname $file)"; mv "$file" "$dir/${dir##*/}.${file##*.}"' \;

#########################
# Additional filtration # 
#########################

# mp3 ONLY (case insensitive) 
find . -mindepth 2 -type f -iname "*.mp3" -exec bash -c 'file="{}"; dir="$(dirname $file)"; mv "$file" "$dir/${dir##*/}.${file##*.}"' \;

# mp3 OR mp4 ONLY (case insensitive)
find . -mindepth 2 -type f \( -iname "*.mp3" -or -iname "*.mp4" \) -exec bash -c 'file="{}"; "dir=$(dirname $file)"; mv "$file" "$dir/${dir##*/}.${file##*.}"' \;

【讨论】:

    【解决方案2】:

    如果你不介意使用外部工具,那么rnm 可以很容易地做到这一点:

    rnm -ns '/pd0/./e/' */*
    

    /pd0/ 是直接父目录,/pd1/ 是之前的目录,依此类推。

    -ns 表示 名称字符串/pd//e/名称字符串规则 扩展为 父目录文件扩展名

    /pd/规则的一般格式为/pd<digit>-<digit>-<delim>/,例如/pd0-2-_/之类的规则将从dir2/dir1/dir0的目录结构构造dir0_dir1_dir2

    更多示例请见here

    【讨论】:

      【解决方案3】:

      试试这个,

      for i in */*; do mv $i $(dirname $i)/$(dirname $i).${i##*.}; done
      

      For 循环逐个遍历目录中的每个文件。 mv 语句将目录中的每个文件一一重命名。

      【讨论】:

        【解决方案4】:

        这样的事情应该可以完成:

        for i in */*; do
            echo mv "${i}" "${i%/*}/${i%/*}.${i##*.}"
        done
        

        参见例如here,这个神秘的参数扩展(如${i%/*})在bash 中意味着什么。

        上面的脚本只会打印控制台中的命令,不会调用它们。一旦确定要继续,您可以删除 echo 语句并让它运行。

        【讨论】:

          猜你喜欢
          • 2013-12-13
          • 2014-09-28
          • 2016-08-01
          • 2020-11-23
          • 1970-01-01
          • 2010-10-27
          • 2022-01-13
          • 1970-01-01
          • 2021-08-20
          相关资源
          最近更新 更多