V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
andybest
V2EX  ›  问与答

Linux Shell 脚本求助

  •  
  •   andybest · 2014-10-02 08:48:30 +08:00 · 3306 次点击
    这是一个创建于 3705 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我的监控摄像头每天产生大量如下格式的视频文件:
    20140928161800_0_0_1000005.mp4
    20140928162003_0_0_1000005.mp4
    20140928162206_0_0_1000005.mp4
    ....

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

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

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

    or

    find ./ -mtime +1 -exec rm -rf {} \;
    Oleg
        5
    Oleg  
       2014-10-02 09:06:26 +08:00   ❤️ 1
    #!/bin/sh
    find /dirname -mtime +1 -name "%Y%m%d*_1000005.mp4" -exec rm -f {} \;
    (未测试)
    fising
        6
    fising  
       2014-10-02 09:09:09 +08:00   ❤️ 2
    楼主你可以通过
    find ./ -mtime +1 -print
    命令来显示符合删除条件的文件列表,用于测试
    andybest
        7
    andybest  
    OP
       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
        8
    Oleg  
       2014-10-02 09:21:59 +08:00   ❤️ 1
    @andybest 囧。。。可以-name试试
    andybest
        9
    andybest  
    OP
       2014-10-02 09:36:26 +08:00   ❤️ 1
    @Oleg 谢谢,关键是怎么得到一个可以 match 24小时之前文件名的 PATTERN ?
    ksunliang
        10
    ksunliang  
       2014-10-02 10:14:45 +08:00   ❤️ 1
    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
        11
    ksunliang  
       2014-10-02 10:22:52 +08:00
    @ksunliang 理解错了,这样保留的仅仅是今天的,而并不是 24 小时前的。
    jasontse
        12
    jasontse  
       2014-10-02 12:21:37 +08:00 via iPad
    @andybest
    从头交叉编译 Findutils 才是出路啊
    http://www.gnu.org/software/findutils/
    achenge07
        13
    achenge07  
       2014-10-02 13:01:08 +08:00
    确定有毫秒信息吗? 我看每个相隔2分零三秒,24小时能拍n=24*60*60/123 = 702.43902439024段,保留最新的703个呗
    kfll
        14
    kfll  
       2014-10-02 17:38:42 +08:00 via Android
    楼主要是嫌麻烦的话,可以先清理一次,然后cron每天清理前一天的
    xylophone21
        15
    xylophone21  
       2014-10-02 18:23:40 +08:00   ❤️ 1
    @kfll 说的没错
    如果不需要特别精确的话
    用date组出20140927字符串,然后rm 20140927*即可。(略改需求)

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

    直接 ls *.mp4 | head -n -703 然后扔给rm不就行了。
    walleL
        17
    walleL  
       2014-10-02 23:30:57 +08:00   ❤️ 1
    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:~#
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2650 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 05:28 · PVG 13:28 · LAX 21:28 · JFK 00:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.