Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash使用序列号对文件夹和子文件夹中的文件进行批量重命名_Bash_Rename_Sequential - Fatal编程技术网

bash使用序列号对文件夹和子文件夹中的文件进行批量重命名

bash使用序列号对文件夹和子文件夹中的文件进行批量重命名,bash,rename,sequential,Bash,Rename,Sequential,我需要一个bash脚本,它执行以下操作: 对于文件夹及其子文件夹中存在的每一个特定类型的文件,它都会在前面加上一个序号(4位数字),后跟一个分隔符(-) 例如,我有: /Queen/(1986) A Kind of Magic/01.One vision.mp3 /Queen/(1986) A Kind of Magic/02.A kind of magic.mp3 /Queen/(1986) A Kind of Magic/cover.jpg /Queen/(1991) Inn

我需要一个bash脚本,它执行以下操作: 对于文件夹及其子文件夹中存在的每一个特定类型的文件,它都会在前面加上一个序号(4位数字),后跟一个分隔符(-)

例如,我有:

  /Queen/(1986) A Kind of Magic/01.One vision.mp3
  /Queen/(1986) A Kind of Magic/02.A kind of magic.mp3
  /Queen/(1986) A Kind of Magic/cover.jpg
  /Queen/(1991) Innuendo/01.Innuendo.mp3
  /Queen/(1991) Innuendo/02.Headlong.mp3
  /Queen/(1991) Innuendo/cover.jpg
  /Queen/(1991) Innuendo/booklet.pdf
我希望在以下脚本的结尾处:

  /Queen/(1986) A Kind of Magic/0001-01.One vision.mp3
  /Queen/(1986) A Kind of Magic/0002-02.A kind of magic.mp3
  /Queen/(1986) A Kind of Magic/cover.jpg
  /Queen/(1991) Innuendo/0003-01.Innuendo.mp3
  /Queen/(1991) Innuendo/0004-02.Headlong.mp3
  /Queen/(1991) Innuendo/cover.jpg
  /Queen/(1991) Innuendo/booklet.pdf
请注意,文件名中有空格,文件夹名中有括号! 我该怎么做?我尝试使用mac automator,但没有成功!:(


感谢您

创建以下bash脚本并在音乐收藏的基本目录中执行。它将与包含空格、括号、单引号和双引号、其他奇怪字符的文件名和目录名一起使用,但与包含换行符或非常奇怪字符的名称一起使用。。您可以自定义它为
start\u dir
输入不同的值,或更改格式规范
%s/%04u-%s
,该规范当前包含
%s
(目录名)
%04u
(编号索引,格式为零填充的四位整数)和
%s
(文件名),由
/
-
分隔

#!/bin/bash
start_dir="."
find "$start_dir" -name '*.mp3' -type f \
  |sort \
  |while read name; do 
     ((i++))
     mv -i "$name" \
       "$(printf '%s/%04u-%s' "$(dirname "$name")" $((i)) "$(basename "$name")")"
   done
备注:

索科维的答案与我的答案非常相似。区别在于(1)他需要bash 4.0,默认情况下它不会安装在Mac电脑上。我不需要。(2)他的脚本可以处理包含换行符的文件名(非常罕见的情况)。我的不会。(3) 如果您的所有mp3文件(包括子目录)的名称的总长度超过262144字节,他的脚本将失败;我想说的是,如果您有大约6000个以上的文件,就会发生这种情况。我的脚本可以处理任意数量的文件


(对于热爱bash的从业人员来说,
mapfile
:我知道使用
mapfile
生成索引可能是一种聪明的方法,而无需显式创建
$I
,但是(I)不需要庞大的数组
mapfile
来创建和(ii)在解析传递给
mv
回调函数的命令行时,我仍然需要一个变量。

以下脚本将当前目录下的所有mp3文件作为前缀,并使用四位数字编号,并且应该适用于所有可能的文件名

#! /bin/bash
shopt -s globstar nullglob
n=0
for f in **/*.mp3; do
        (( ++n ))
        b="$(basename "$f")"
        mv -i "$f" "${f%"$b"}/$(printf '%04d' "$n")-$b"
done
globstar
**
需要bash>4.0,据我所知,它没有预装在Mac电脑上(请查看
bash--version
),但我听说有办法安装较新的bash版本


文件的编号顺序取决于您的区域设置。Bash根据
LC\u-COLLATE
以排序方式展开
***
。至少对于
LC\u-COLLATE=en\u-US。UTF-8
文件按字母顺序编号,我们不必担心名称冲突–顺序保证不会覆盖发生。

很好的解决方案,避免了
find
和后续的
sort
。但是,将所有路径名放在一个命令行中可能会遇到BSD
ARG_MAX
限制262144字节。估计每个路径名的平均值为45字节(根据我自己的音乐收藏衡量…),这将在大约6000个文件中发生。。。