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

2014-02-08 22:19:16 +08:00
 Droog
问题描述如下:
目录下有一批文件,如:
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的能否指点下,谢谢。
9845 次点击
所在节点    Linux
17 条回复
likexian
2014-02-08 22:30:00 +08:00
chenyg32
2014-02-08 22:34:15 +08:00
今天我在Windows上也碰到这个问题哈哈,想着要是在Linux下就好弄一点……只要读取时间和重命名的命令就行了,对吧?
Droog
2014-02-08 22:39:19 +08:00
@likexian 谢谢,看看先;

@chenyg32 对的,就是这个意思。
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
2014-02-08 23:30:53 +08:00
ls --full-time 获取文件的信息
awk 截取出文件的时间
date -d "timestamp" +%s 获取unix timestamp
然后mv old new
mv之前加上文件是否存在判断就好了,防止重名。
LazyZhu
2014-02-08 23:39:08 +08:00
shell很简单就能解决,但是时间戳(date +%s)间隔是秒,如果以时间戳为文件名的话,命令里面必须加个sleep 1,否则一秒内只会重命名一个文件,其他会被覆盖。
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
2014-02-08 23:52:08 +08:00
@LazyZhu 好吧 原来是操作的时间是当前时间么。。。
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
2014-02-09 00:23:01 +08:00
在photo的上级目录中执行。比如/tmp/photo里是照片,进入目录/tmp运行那一句命令就可以了。
jasontse
2014-02-09 08:50:06 +08:00
@LazyZhu sleep浪费时间,直接自增就好了。
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
2014-02-09 09:36:52 +08:00
修正上面最后一行的错误
$new_name = str_replace('.', '', microtime(TRUE)) . ".{$h}";

不过正如前面所说的,直接用自增也可以的...
vibbow
2014-02-09 09:43:52 +08:00
不知道为什么,其他人的头像加载都正常,就是默认的火星头像在我这里经常性的加载失败。
cc @livid
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
2014-02-10 11:00:04 +08:00
@jpuyy
“操作的时间戳” 是个什么意思?我重命名的操作的时间戳?如果到秒的话必然会冲突啊……
楼主的意思大概是文件生成的时间戳?

for i in *.jpg;do mv $i `stat $i -c %Y`.jpg;done
rrfeng
2014-02-10 11:01:57 +08:00
注意冲突,毕竟这些文件可能有同一秒生成的……

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

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

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

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

© 2021 V2EX