【问题标题】:Grabbing every 4th file抓取每 4 个文件
【发布时间】:2010-09-09 11:07:45
【问题描述】:

我有 16,000 张来自 webcan 屏幕抓取器的 jpg,我让它们运行了一年,指向后一年。我想找到一种方法来抓取每 4 个图像,以便我可以将它们放入另一个目录,以便以后将它们变成电影。 linux下有没有简单的bash脚本或其他方式可以做到这一点。

他们的名字是这样的......

frame-44558.jpg

frame-44559.jpg

frame-44560.jpg

frame-44561.jpg

感谢需要帮助的新手。


似乎奏效了。 我的原始帖子中有几个错误。实际上有 280,000 张图像,命名是。 /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163405.jpg /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163505.jpg /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163605.jpg

我跑了。 cp $(ls | awk '{nr++; if (nr % 10 == 0) print $0}') ../newdirectory/

这似乎复制了图像。从外观上看,每天 70-900 个。

现在我正在跑步 mencoder mf://*.jpg -mf w=640:h=480:fps=30:type=jpg -ovc lavc -lavcopts vcodec=msmpeg4v2 -nosound -o ../output-msmpeg4v2.avi

我会让你知道这部电影的效果。

更新:电影无法播放。 尽管目录中也有 2008 年,但其中只有 2007 年的图像。 webcam_2008-02-17_101403.jpg webcam_2008-03-27_192205.jpg webcam_2008-02-17_102403.jpg webcam_2008-03-27_193205.jpg webcam_2008-02-17_103403.jpg webcam_2008-03-27_194205.jpg webcam_2008-02-17_104403.jpg webcam_2008-03-27_195205.jpg

如何修改我的 mencoder 线以使用所有图像?

【问题讨论】:

    标签: bash scripting


    【解决方案1】:

    按照建议,您应该使用

    seq -f 'frame-%g.jpg' 1 4 number-of-frames
    

    生成文件名列表,因为 'ls' 将在 280k 文件上失败。所以最终的解决方案是这样的:

    for f in `seq -f 'frame-%g.jpg' 1 4 number-of-frames` ; do
      mv $f destdir/
    done
    

    【讨论】:

      【解决方案2】:

      这很俗气,但应该可以完成工作。假设您当前 cd'd 进入包含所有文件的目录:

      mkdir ../outdir
      ls | sort -n | while read fname; do mv "$fname" ../outdir/; read; read; read; done
      

      sort -n 假设您的文件名的位数不完全相同;否则ls 将按词汇顺序排序,其中frame-123.jpg 在frame-4.jpg 之前,我认为这不是你想要的。

      请小心,在尝试我的解决方案之前备份您的文件等。我不想为您丢失一年的数据负责。

      请注意,与大多数其他解决方案不同,此解决方案确实可以处理名称中带有空格的文件。我知道这不是示例文件名的一部分,但是很容易编写不能安全处理空格的 shell 命令,所以我想在这个示例中这样做。

      【讨论】:

        【解决方案3】:

        鉴于 masto 关于排序的注意事项:

        ls | sed -n '1~4 p' | xargs -i mv {} ../destdir/

        我喜欢这个解决方案的一点是,一切都在按照它的设计目的做,所以我觉得它很单一。

        【讨论】:

          【解决方案4】:

          perl 中的一种简单方法(可能很容易适应 bash)是将文件名全局化到一个数组中,然后获取序列号并删除不能被 4 整除的那些

          这样的东西会打印你需要的文件:

          ls -1 /path/to/files/ | perl -e 'while (<STDIN>) {($seq)=/(\d*)\.jpg$/; print $_ if $seq && $seq % 4 ==0}'
          

          您可以通过移动替换打印...

          如果文件按顺序编号,即使位数不是恒定的,例如 file_9.jpg 后跟 file_10.jpg,这将起作用)

          【讨论】:

            【解决方案5】:

            只需遍历文件列表:

            files=( frame-*.jpg )
            i=0
            while [[ $i -lt ${#files} ]] ; do
              cur_file=${files[$i]}
              mungle_frame $cur_file
              i=$( expr $i + 4 )
            done
            

            【讨论】:

            • 我不明白files=( frame-*.jpg ),这是在做什么?我在 shell 中尝试过,它只给了我一个分配给变量的文件名
            【解决方案6】:
            seq -f 'frame-%g.jpg' 1 4 number-of-frames
            

            ...将打印您需要的文件的名称。

            【讨论】:

              【解决方案7】:

              创建一个包含以下内容的脚本 move.sh:

              #!/bin/sh
              mv $4 ../newdirectory/
              

              使其可执行,然后在文件夹中执行此操作:

              ls *.jpg | xargs -n 4 ./move.sh
              

              这会获取文件名列表,一次将四个传递到 move.sh,然后忽略前三个并将第四个移动到新文件夹中。

              即使数字不完全按顺序,这也会起作用(例如,如果缺少某些帧编号,则使用 mod 4 算法将不起作用)。

              【讨论】:

              • ls *.jpg | xargs -n 10 ./copy.sh bash: /bin/ls: 参数列表太长 cp: cannot stat `0': No such file or directory
              • 我犯了一个错误。有 280,000 张图片 :)
              【解决方案8】:

              一个简单的方法是:

              $ touch a b c d e f g h i j k l m n o p q r s t u v w x y z $ mv $(ls | awk '{nr++; if (nr % 4 == 0) print $0}') destdir

              【讨论】:

              • 也许你应该指出第一行不是必需的,它只是创建示例数据......
              猜你喜欢
              • 2011-05-30
              • 1970-01-01
              • 2015-04-18
              • 1970-01-01
              • 2013-07-12
              • 2019-07-28
              • 2021-05-26
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多