每个文件夹中按顺序取出一个文件,并按顺序存入新的文件夹

应邀做数据预处理,需求是这样的。

每个文件夹中按顺序取出一个文件,并按顺序存入新的文件夹_图片预处理

一共20个有效文件夹,每个文件夹中是这样的

每个文件夹中按顺序取出一个文件,并按顺序存入新的文件夹_bash shell_02


需求是:​​每个文件夹中的第一个图片放在一起,第二个图片放在一起,以此类推。现在是20个文件夹,每个文件夹有56张图片,处理后的结果是一共有56个文件夹,每个文件夹中有20张图片​​。

图片命名预处理

因为原始图片的命名并不利于按顺序查找文件,我们将其重命名。

这里我们要考虑一下重命名的方式:

  1. 首先,为了后期检查或者查找方便,我们把原始的文件夹名带上,这样汇总后的文件知道是从哪个文件夹来的;
  2. 文件名中还要有文件的索引序号;
  3. 原始的文件名不要动,为了后期检查;

所以,根据这几个规则,我们重命名后的文件名将是:

每个文件夹中按顺序取出一个文件,并按顺序存入新的文件夹_文件预处理_03

这种形式。
第一组数字代表文件来自哪个文件夹,如第一张图所示;第二个数字代表文件的索引号,如第二张图所示,后面的是原始文件名。

创建名为rename.sh的文件。

cd 720  #720为文件主目录
vi

关于vi和其他一些说明请参考对文件预处理的上一篇文章,​​从大量文件中找到指定文件并执行指定文件操作​​,这里面介绍了更多的细节,因为已经介绍过,这篇将不再介绍基础的细节,而只专注于代码实现。

在rename.sh中,输入以下代码

#!/bin/bash

for folder in * # 遍历所有文件夹
do
cd $folder

INDEX=1 # 用来确定文件的索引序号
for f in * # 遍历所有文件
do
cp -- "$f" "$folder-$INDEX-$f" # -- 必须要有,为什么要复制而不是直接对源文件重命名呢,因为保留源文件是个不错的习惯
((INDEX++)) # 对于数学的运算,有很多方法,(())嵌套括号是其中之一
done

cd .. # 跳进了子文件夹,不要忘记跳出去
done

这就是对所有文件重命名的代码。

创建文件夹用来存放按需处理后的文件

处理后是56个文件夹,每个文件夹20个文件。所以直接创建一个大文件夹和56个子文件夹。子文件夹的命名就以数字序号来表示。

这句指令较为简短,便不以脚本程序的方式来执行,直接在终端中输入敲回车即可。

for((i=1; i<=56; i=i+1)); do mkdir -p ./temp/$i; done

每个文件夹中按顺序取出一个文件,并按顺序存入新的文件夹_shell 文件操作_04


新建后的目录结构如图。

移动对应的文件到temp文件夹

我们要将每个文件夹中序号为1的图片移动到/temp/1文件夹,以此类推。

创建file.sh。

#!/bin/bash

for ((i=1; i<=56; i=i+1))
do
f="*-$i-*.bmp" # 只需要对i进行匹配,其他的都通配就可以
find -iname $f -type f -exec mv {} ./temp/$i \;
# 这里为什么要用mv直接移动而不是复制呢,直接移动有助于检查是否还有漏下的文件没有
# 被移动过去,便于debug
done

完成后,temp文件夹的目录结构就是这样的

每个文件夹中按顺序取出一个文件,并按顺序存入新的文件夹_文件预处理_05


即每个文件夹中对应序号的文件存放在对应序号的文件夹中。

Windows用户操作方法

win10(非家庭版)用户请参考​​这篇文章​​,然后再回来看指令和代码。