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