Linux Shell 脚本求助

2014-10-02 08:48:30 +08:00
 andybest
我的监控摄像头每天产生大量如下格式的视频文件:
20140928161800_0_0_1000005.mp4
20140928162003_0_0_1000005.mp4
20140928162206_0_0_1000005.mp4
....

格式为:年+月+日+小时+分钟+秒+毫秒+_0_0_1000005.mp4

要写一个 Shell 脚本(用于在 Crontab 中自动运行)删除 24 小时之前的视频文件,如何做?
感谢!
3330 次点击
所在节点    问与答
17 条回复
bcxx
2014-10-02 08:51:22 +08:00
纯 shell 的话就用 date 来求 time difference 然后删除就好了吧

当然你想好看点可以直接用 python 之类的脚本来写 datetime ~_~
fising
2014-10-02 08:56:08 +08:00
find ./ -mtime 1 -delete
fising
2014-10-02 08:57:57 +08:00
未测试,反正命名是 find xxxx -delete
fising
2014-10-02 09:04:56 +08:00
find ./ -mtime +1 -delete

or

find ./ -mtime +1 -exec rm -rf {} \;
Oleg
2014-10-02 09:06:26 +08:00
#!/bin/sh
find /dirname -mtime +1 -name "%Y%m%d*_1000005.mp4" -exec rm -f {} \;
(未测试)
fising
2014-10-02 09:09:09 +08:00
楼主你可以通过
find ./ -mtime +1 -print
命令来显示符合删除条件的文件列表,用于测试
andybest
2014-10-02 09:12:28 +08:00
@fising @Oleg 多谢,mtime 参数非常灵,可在 OpenWrt 上竟不支持 mtime 参数:

root@OpenWrt:# find --help
BusyBox v1.19.4 (2014-03-23 07:54:36 CET) multi-call binary.

Usage: find [PATH]... [OPTIONS] [ACTIONS]

Search for files and perform actions on them.
First failed action stops processing of current file.
Defaults: PATH is current directory, action is '-print'

-follow Follow symlinks
-xdev Don't descend directories on other filesystems
-maxdepth N Descend at most N levels. -maxdepth 0 applies
actions to command line arguments only
-mindepth N Don't act on first N levels
-depth Act on directory *after* traversing it

Actions:
( ACTIONS ) Group actions for -o / -a
! ACT Invert ACT's success/failure
ACT1 [-a] ACT2 If ACT1 fails, stop, else do ACT2
ACT1 -o ACT2 If ACT1 succeeds, stop, else do ACT2
Note: -a has higher priority than -o
-name PATTERN Match file name (w/o directory name) to PATTERN
-iname PATTERN Case insensitive -name
-path PATTERN Match path to PATTERN
-ipath PATTERN Case insensitive -path
-regex PATTERN Match path to regex PATTERN
-type X File type is X (one of: f,d,l,b,c,...)
-perm MASK At least one mask bit (+MASK), all bits (-MASK),
or exactly MASK bits are set in file's mode
-user NAME/ID File is owned by given user
-group NAME/ID File is owned by given group
-size N[bck] File size is N (c:bytes,k:kbytes,b:512 bytes(def.))
+/-N: file size is bigger/smaller than N
-prune If current file is directory, don't descend into it
If none of the following actions is specified, -print is assumed
-print Print file name
-print0 Print file name, NUL terminated
-exec CMD ARG ; Run CMD with all instances of {} replaced by
file name. Fails if CMD exits with nonzero
Oleg
2014-10-02 09:21:59 +08:00
@andybest 囧。。。可以-name试试
andybest
2014-10-02 09:36:26 +08:00
@Oleg 谢谢,关键是怎么得到一个可以 match 24小时之前文件名的 PATTERN ?
ksunliang
2014-10-02 10:14:45 +08:00
v$ ls

20140928161800_0_0_1000005.mp4 20140930162011_0_0_1000005.mp4
20140928162003_0_0_1000005.mp4 20140930162019_0_0_1000005.mp4
20140928162006_0_0_1000005.mp4 20141001161800_0_0_1000005.mp4
20140928162011_0_0_1000005.mp4 20141001162003_0_0_1000005.mp4
20140928162019_0_0_1000005.mp4 20141001162006_0_0_1000005.mp4
20140929161800_0_0_1000005.mp4 20141001162011_0_0_1000005.mp4
20140929162003_0_0_1000005.mp4 20141001162019_0_0_1000005.mp4
20140929162006_0_0_1000005.mp4 20141002161800_0_0_1000005.mp4
20140929162011_0_0_1000005.mp4 20141002162003_0_0_1000005.mp4
20140929162019_0_0_1000005.mp4 20141002162006_0_0_1000005.mp4
20140930161800_0_0_1000005.mp4 20141002162011_0_0_1000005.mp4
20140930162003_0_0_1000005.mp4 20141002162019_0_0_1000005.mp4
20140930162006_0_0_1000005.mp4

v$ rm -f $(ls *.mp4| grep -v "$(date +%Y%m%d)")

20140928161800_0_0_1000005.mp4
20140928162003_0_0_1000005.mp4
20140928162006_0_0_1000005.mp4
20140928162011_0_0_1000005.mp4
20140928162019_0_0_1000005.mp4
20140929161800_0_0_1000005.mp4
20140929162003_0_0_1000005.mp4
20140929162006_0_0_1000005.mp4
20140929162011_0_0_1000005.mp4
20140929162019_0_0_1000005.mp4
20140930161800_0_0_1000005.mp4
20140930162003_0_0_1000005.mp4
20140930162006_0_0_1000005.mp4
20140930162011_0_0_1000005.mp4
20140930162019_0_0_1000005.mp4
20141001161800_0_0_1000005.mp4
20141001162003_0_0_1000005.mp4
20141001162006_0_0_1000005.mp4
20141001162011_0_0_1000005.mp4
20141001162019_0_0_1000005.mp4

v$ ls

20141002161800_0_0_1000005.mp4 20141002162011_0_0_1000005.mp4
20141002162003_0_0_1000005.mp4 20141002162019_0_0_1000005.mp4
20141002162006_0_0_1000005.mp4
ksunliang
2014-10-02 10:22:52 +08:00
@ksunliang 理解错了,这样保留的仅仅是今天的,而并不是 24 小时前的。
jasontse
2014-10-02 12:21:37 +08:00
@andybest
从头交叉编译 Findutils 才是出路啊
http://www.gnu.org/software/findutils/
achenge07
2014-10-02 13:01:08 +08:00
确定有毫秒信息吗? 我看每个相隔2分零三秒,24小时能拍n=24*60*60/123 = 702.43902439024段,保留最新的703个呗
kfll
2014-10-02 17:38:42 +08:00
楼主要是嫌麻烦的话,可以先清理一次,然后cron每天清理前一天的
xylophone21
2014-10-02 18:23:40 +08:00
@kfll 说的没错
如果不需要特别精确的话
用date组出20140927字符串,然后rm 20140927*即可。(略改需求)

如果要求精确高的话,列出所有文件,一个一个比吧,希望组出一个rm命令还是比较麻烦的。
msg7086
2014-10-02 21:55:20 +08:00
保留最新的703个是个不错的想法,而且其实不一定是703个吧,保留1000个不行么 -_-

直接 ls *.mp4 | head -n -703 然后扔给rm不就行了。
walleL
2014-10-02 23:30:57 +08:00
root@OpenWrt:~# ls *.mp4 -1
20140928162206_0_0_1000005.mp4
20141001152206_0_0_1000005.mp4
20141001154006_0_0_1000005.mp4
20141001162206_0_0_1000005.mp4
20141002162206_0_0_1000005.mp4
root@OpenWrt:~# sh d.sh
/bin/rm -vf 20140928162206_0_0_1000005.mp4
/bin/rm -vf 20141001152206_0_0_1000005.mp4
root@OpenWrt:~# date
Thu Oct 2 15:25:37 UTC 2014
root@OpenWrt:~# cat d.sh
#!/bin/sh
CUT_TIME=$(date -d@$(($(date +%s)-86400)) +%s)
ls *_0_0_1000005.mp4 | while read FILE;do
FILE_TIME=$(echo "$FILE" | cut -c1-12 | xargs date +%s -d)
test $FILE_TIME -lt $CUT_TIME && echo /bin/rm -vf "$FILE"
done
root@OpenWrt:~#

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/136760

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX