V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
Droog
V2EX  ›  Linux

Linux下根据时间戳批量重命名文件

  •  
  •   Droog · 2014-02-08 22:19:16 +08:00 · 9826 次点击
    这是一个创建于 3933 天前的主题,其中的信息可能已经有所发展或是发生改变。
    问题描述如下:
    目录下有一批文件,如:
    DSC05217.jpg
    DSC05221.jpg
    DSC05232.jpg
    DSC05243.jpg
    DSC05272.jpg
    DSC05294.jpg
    DSC05297.jpg
    DSC05302.jpg
    DSC05316.jpg
    DSC05319.jpg
    DSC05338.jpg
    DSC05344.jpg
    DSC05355.jpg

    现需要将文件根据操作的时间戳进行批量重命名,扩展名不变:
    如:DSC05355.jpg重命名为1294289727.jpg
    熟悉shell的能否指点下,谢谢。
    17 条回复    1970-01-01 08:00:00 +08:00
    chenyg32
        2
    chenyg32  
       2014-02-08 22:34:15 +08:00   ❤️ 1
    今天我在Windows上也碰到这个问题哈哈,想着要是在Linux下就好弄一点……只要读取时间和重命名的命令就行了,对吧?
    Droog
        3
    Droog  
    OP
       2014-02-08 22:39:19 +08:00
    @likexian 谢谢,看看先;

    @chenyg32 对的,就是这个意思。
    txlty
        4
    txlty  
       2014-02-08 23:12:19 +08:00
    php写命令行脚本很强大又简单又跨平台,咋就没人用呢??
    <?php
    $dirname=$argv[1];
    if($argc!=2){
    exit('use like c:\>php name.php dirname/');
    }
    $dir=scandir($dirname);
    array_shift($dir);
    array_shift($dir);
    foreach($dir as $filename){
    $arr=explode('.',$filename);
    $h=array_pop($arr);
    $newname=filemtime($dirname.$file).'.'.$h;
    rename($dirname.$filename,$dirname.$newname);
    echo "change name [".$filename."] to [".$newname."]\n";
    }
    echo 'finish!';
    ?>
    使用 >php name.php 图片目录/
    wang2191195
        5
    wang2191195  
       2014-02-08 23:30:53 +08:00
    ls --full-time 获取文件的信息
    awk 截取出文件的时间
    date -d "timestamp" +%s 获取unix timestamp
    然后mv old new
    mv之前加上文件是否存在判断就好了,防止重名。
    LazyZhu
        6
    LazyZhu  
       2014-02-08 23:39:08 +08:00
    shell很简单就能解决,但是时间戳(date +%s)间隔是秒,如果以时间戳为文件名的话,命令里面必须加个sleep 1,否则一秒内只会重命名一个文件,其他会被覆盖。
    txlty
        7
    txlty  
       2014-02-08 23:43:20 +08:00
    更正!!!我写的是文件最后修改时间,楼主要的应该是改名操作时的时间。
    修改了一下。
    <?php
    $dirname=$argv[1];
    if($argc!=2){
    exit('use like c:\>php name.php dirname/');
    }
    $dir=scandir($dirname);
    array_shift($dir);
    array_shift($dir);
    foreach($dir as $filename){
    $arr=explode('.',$filename);
    $h=array_pop($arr);
    $newname=getmicrotime().'.'.$h;
    rename($dirname.$filename,$dirname.$newname);
    echo "change name [".$filename."] to [".$newname."]\n";
    usleep(50000);
    }
    echo 'finish!';
    function getmicrotime(){
    list($usec, $sec) = explode(" ", microtime());
    $arr=explode('.',$usec);
    $usec=array_pop($arr);
    return $sec.$usec;
    }
    ?>
    wang2191195
        8
    wang2191195  
       2014-02-08 23:52:08 +08:00
    @LazyZhu 好吧 原来是操作的时间是当前时间么。。。
    adrianzhang
        9
    adrianzhang  
       2014-02-09 00:18:09 +08:00
    将这些文件放在文件夹photo中,然后在photo平级的目录中执行
    shell执行:

    for i in `ls photo`; do mv photo/$i photo/`stat $i |grep -i Modify | awk -F. '{print $1}' | awk '{print $2$3}'| awk -F- '{print $1$2$3}' | awk -F: '{print $1$2$3}'`.jpg; done
    adrianzhang
        10
    adrianzhang  
       2014-02-09 00:23:01 +08:00
    在photo的上级目录中执行。比如/tmp/photo里是照片,进入目录/tmp运行那一句命令就可以了。
    jasontse
        11
    jasontse  
       2014-02-09 08:50:06 +08:00 via iPad
    @LazyZhu sleep浪费时间,直接自增就好了。
    vibbow
        12
    vibbow  
       2014-02-09 09:29:39 +08:00
    @txlty
    你用两次array_shift感觉不如直接写 if ($filename == '.' || $filename == '..') continue; 来的容易理解些,反正都用PHP了也就不需要特别在乎效率了。
    其次要判断文件名是否是目录。
    然后你用在获取文件扩展名的时候用了explode,感觉用pathinfo函数更好理解些。
    你不知道microtime这个函数可以接受一个Boolean参数的么?(你重复造了一个PHP已经存在的轮子)。

    $newname=getmicrotime().'.'.$h;
    这句话我非常想重写成以下形式,虽然不知道是不是好习惯
    $new_name = microtime(TRUE) . ".{$h}";
    vibbow
        13
    vibbow  
       2014-02-09 09:36:52 +08:00
    修正上面最后一行的错误
    $new_name = str_replace('.', '', microtime(TRUE)) . ".{$h}";

    不过正如前面所说的,直接用自增也可以的...
    vibbow
        14
    vibbow  
       2014-02-09 09:43:52 +08:00
    不知道为什么,其他人的头像加载都正常,就是默认的火星头像在我这里经常性的加载失败。
    cc @livid
    jpuyy
        15
    jpuyy  
       2014-02-09 21:37:38 +08:00
    lz试试这个,前提是也要判断一个文件是否存在
    for i in `ls`
    do
    mv $i `ls -l $i | awk '{print $6, $7, $8}'| while read LINE; do date -d "$LINE" +%s; done`.jpg
    done
    rrfeng
        16
    rrfeng  
       2014-02-10 11:00:04 +08:00   ❤️ 1
    @jpuyy
    “操作的时间戳” 是个什么意思?我重命名的操作的时间戳?如果到秒的话必然会冲突啊……
    楼主的意思大概是文件生成的时间戳?

    for i in *.jpg;do mv $i `stat $i -c %Y`.jpg;done
    rrfeng
        17
    rrfeng  
       2014-02-10 11:01:57 +08:00
    注意冲突,毕竟这些文件可能有同一秒生成的……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2616 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 15:37 · PVG 23:37 · LAX 07:37 · JFK 10:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.