ubuntu 使用shell脚本遍历文件夹下的所有子目录并将每个子目录中的所有图片转换为视频

问题描述

想要通过shell脚本完成对某个数据集的处理,具体包括:

  • 对该数据集(一个文件夹,如dataset)下的所有子目录进行遍历, 目录结构如下:
dataset
    |--real_train
           |--0.tar.gz
           |--1.tar.gz
           |--2.tar.gz
           ...
    |--real_test
           |--0.tar.gz
           |--1.tar.gz
           |--2.tar.gz
           ...
    |--fake_train
           |--0.tar.gz
           |--1.tar.gz
           |--2.tar.gz
           ...
    |--fake_test
           |--0.tar.gz
           |--1.tar.gz
           |--2.tar.gz
           ...

其中,每个压缩文件.tar.gz解压后的又包括了层数固定的子文件夹,如:

0.tar.gz
    |--real
           |--8
                --23.png
                --24.png
                --25.png
                ...
           |--9
                --256.png
                --248.png
                --223.png
                ...
           |--11
                --203.png
                --223.png
                --283.png
                ...

需要一直遍历到最后一层包含多张png图像的目录,如a.tar.gz解压缩后的/real/8/.

  • 将每一个目录下的png图片合成一个视频;
  • 将合并成的视频统一保存到目录~/video/下,并以该视频原本的目录进行命名以区分,如~/video/real_train_0_real_8.mp4.

 

思路

  • 使用for循环遍历每一个目录,如 for f in `ls`.

          当需要仅遍历文件夹时,通过设置ls命令参数for f0 in `ls -F | grep "/$"` 以及 字符串匹配去掉\, f1=${f0%/*}实现;

出错的地方:

  • 拼接字符串时双引号外绝不能有空格, 平时空格、符号前后加空格的习惯反而会报错!
  • bash不支持/符号,因此保存视频时filename中不能出现\ ,否则ffmpeg会报错 No such file or directory. 应将/符号转移到ffmpeg中使用,如下面的代码所示。

 

代码

# script to create movie from multiple png files
# taken in choronoligcal order

# real_test, real_train, fake_test, fake_train
for f0 in `ls -F | grep "/$"`
do
  f1=${f0%/*}
  cd ./$f1
  # 3.tar.gz, 6.tar.gz, 8.tar.gz
  for f2zip in `ls -rt *.tar.gz`
  do
    # 解压当前文件
    tar -xvf $f2zip
  done
  # 先解压完全部文件,再提取视频
  # 3/, 6/, 9/
  for f2 in `ls -F | grep "/$"`
  do
    # 3, 6, 9
    # f2F=${f%/*}
    cd ./${f2%/*}
    # real
    for f3 in `ls`
    do
      cd ./$f3
      # 56, 59, 95, 110
      for f4 in `ls`
      do
        cd ./$f4
        # start at 0
        count=0
        # take all files named shot - something ordered by date
        for f in `ls -rt *.png`
        do  
            # get the index in 0000 format
            printf $count
            printf -v counts "%04d" $count
              # link file to a frame_0000  named symbolic link
              ln -s $f frame_$counts.png
              # increment counter
            count=`expr $count + 1`
        done
        # create movie
        # slowed down by factor 5
        filename=$f1"_"${f2%/*}"_"$f3"_"$f4
        ffmpeg -f image2 -i frame_%04d.png -vcodec mpeg4 -vf "setpts=5*PTS" ~/video/"$filename".mp4
        # ffmpeg -i frame_%04d.png movie.mp4
        # remove the links
        rm frame_*.png
        cd ../
      done
      cd ../
    done
    cd ../
  done
  cd ../
done

结果

通过上述的脚本,~/video/下生成的视频如下所示:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R.X. NLOS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值