Bash 抓取每4个文件

Bash 抓取每4个文件,bash,scripting,Bash,Scripting,我有16000个jpg,来自一个网络摄像头的尖叫声捕捉器,我让它运行了一年,指向过去的一年。我想找到一种方法来抓取每4张图片,这样我就可以把它们放到另一个目录中,这样我以后就可以把它们变成电影了。linux下是否有一个简单的bash脚本或其他方法可以实现这一点 他们是这样命名的 frame-44558.jpg 帧-44559.jpg frame-44560.jpg frame-44561.jpg 感谢一位需要帮助的新手 似乎已经奏效了。 我的原始帖子中有几个错误。实际上有28万张图片,而且命名

我有16000个jpg,来自一个网络摄像头的尖叫声捕捉器,我让它运行了一年,指向过去的一年。我想找到一种方法来抓取每4张图片,这样我就可以把它们放到另一个目录中,这样我以后就可以把它们变成电影了。linux下是否有一个简单的bash脚本或其他方法可以实现这一点

他们是这样命名的

frame-44558.jpg

帧-44559.jpg

frame-44560.jpg

frame-44561.jpg

感谢一位需要帮助的新手


似乎已经奏效了。 我的原始帖子中有几个错误。实际上有28万张图片,而且命名很简单。 /home/baldy/Desktop/WebCammages/webcam_2007-05-29_163405.jpg /主页/秃顶/桌面/网络摄像机/网络摄像机2007-05-29_163505.jpg /主页/秃顶/桌面/网络摄像机/网络摄像机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年的图片。 网络摄像头2008-02-17_101403.jpg网络摄像头2008-03-27_192205.jpg 网络摄像头2008-02-17_102403.jpg网络摄像头2008-03-27_193205.jpg 网络摄像头2008-02-17_103403.jpg网络摄像头2008-03-27_194205.jpg 网络摄像头2008-02-17_104403.jpg网络摄像头2008-03-27_195205.jpg

如何修改mencoder行以使其使用所有图像?

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

类似的内容将打印您需要的文件:

ls -1 /path/to/files/ | perl -e 'while (<STDIN>) {($seq)=/(\d*)\.jpg$/; print $_ if $seq && $seq % 4 ==0}'
ls-1/path/to/files/| perl-e'while(){($seq)=/(\d*)\.jpg$/;print$uuIf$seq&&$seq%4==0}
您可以通过移动替换打印

如果文件按顺序编号,即使位数不是恒定的,如
file_9.jpg
后跟
file_10.jpg

一种简单的方法是:

$ 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 $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++;如果(nr%4==0)打印$0})destdir
创建包含以下内容的脚本move.sh:

#!/bin/sh
mv $4 ../newdirectory/
使其可执行,然后在文件夹中执行此操作:

ls *.jpg | xargs -n 4 ./move.sh
这将获取文件名列表,一次将四个文件名传递到move.sh中,然后move.sh将忽略前三个文件名,并将第四个文件名移动到新文件夹中

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


…将打印所需文件的名称。

只需在文件列表上迭代即可:

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

这是相当俗气的,但它应该完成工作。假设您当前已将cd刻录到包含所有文件的目录中:

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命令很容易,所以我想在本例中这样做。

给出了masto关于排序的注意事项:

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


我喜欢这个解决方案的一点是,所有的东西都在做它设计要做的事情,所以我觉得它很单一。

正如建议的那样,您应该使用

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

也许您应该指出,第一行不是必需的,它只是创建示例数据…ls*.jpg | xargs-n 10./copy.sh bash:/bin/ls:Argument list太长cp:cannot stat`0':没有这样的文件或目录我犯了一个错误。共有28万张图片:)我不明白
文件=(frame-*.jpg)
,那是干什么的?我在shell中尝试了它,它只给了我一个分配给变量的文件名
for f in `seq -f 'frame-%g.jpg' 1 4 number-of-frames` ; do
  mv $f destdir/
done