如何按文件大小匹配文件并相应地重命名?

时间:2011-08-16 19:28:23

标签: php bash shell comparison rename

我有两个名称不匹配的图像目录,但主要是匹配的图像。

Dir 1       Size   | Dir 2                  Size
---------------------------------------------------
img1.jpg    508960 | a_image_name.jpg       1038644
img2.jpg    811430 | another_image_name.jpg 396240
...         ...    | ...                    ...
img1000.jpg 602583 | image_name.jpg         811430
...         ...    | 
img2000.jpg 396240 | 

第一个目录有更多图像,但名称不正确。第二个目录具有正确的名称,但不对应于第一个目录。

我想通过将文件大小(或其他方式)与Dir 2进行比较来重命名Dir 1中的文件。在上面的示例中,img2.jpg将重命名为image_name.jpg,因为它们具有相同的文件大小。 / p>

你能指出我正确的方向吗?

最好通过app(Mac),shell或php。

2 个答案:

答案 0 :(得分:3)

使用文件的散列而不是使用filesize会更明智吗?

简而言之:使用glob(),获取dir1中的文件列表,迭代,创建md5-hash(md5()+ file_get_contents()),存储在数组中,使用哈希作为键,文件名作为值。 为dir2做同样的事。

迭代array1,如果array2重命名文件

中存在具有相同散列的条目

代码将是这样的:(未经测试,未经优化)

$dir1 = array();
$dir2 = array();

// get hashes for dir1
foreach( glob( '/path/to/dir1/*.jpg' ) as $file ) {
 $hash = md5( file_get_contents( $file ) );
 $dir1[ $hash ] = $file;
}

// repeat for dir2 ...

foreach( $dir1 as $hash => $file1 ) {
 if( array_key_exists( $hash, $dir2 ) ) {
  rename( $file1, $dir2[ $hash ] );
 }
}

答案 1 :(得分:2)

这是我的解决方案,它根据文件大小重命名dir1中的文件。

dir1的内容:

-rw-r--r--  1 haiv  staff   10 Aug 16 13:18 file1.txt
-rw-r--r--  1 haiv  staff   20 Aug 16 13:18 file2.txt
-rw-r--r--  1 haiv  staff   30 Aug 16 13:18 file3.txt
-rw-r--r--  1 haiv  staff  205 Aug 16 13:18 file4.txt

(注意第五列存储文件大小。)和dir2的内容:

-rw-r--r--  1 haiv  staff   30 Aug 16 13:18 doc.txt
-rw-r--r--  1 haiv  staff  205 Aug 16 13:18 dopey.txt
-rw-r--r--  1 haiv  staff   20 Aug 16 13:18 grumpy.txt
-rw-r--r--  1 haiv  staff   10 Aug 16 13:18 happy.txt

创建一个文件调用〜/ rename.awk(是的,从主目录,以避免污染dir1或dir2):

/^total/ {next} # Skip the first line (which contains the total, of ls -l)

{
    if (name[$5] == "") {
        name[$5] = $NF
        print "# File of size", $5, "should be named", $NF
    } else {
        printf "mv '%s' '%s'\n", $NF, name[$5]
    }
}

现在,cd进入dir1(如果要重命名dir1中的文件),并发出以下命令:

$ awk -f ~/rename.awk <(ls -l ../dir2) <(ls -l)

输出:

# File of size 30 should be named doc.txt
# File of size 205 should be named dopey.txt
# File of size 20 should be named grumpy.txt
# File of size 10 should be named happy.txt
mv 'file1.txt' 'happy.txt'
mv 'file2.txt' 'grumpy.txt'
mv 'file3.txt' 'doc.txt'
mv 'file4.txt' 'dopey.txt'

对结果感到满意后,将上述命令传递给sh以执行更改:

$ awk -f ~/rename.awk <(ls -l ../dir2) <(ls -l) | sh

注意:

  1. 无法防范大小相同的文件。为此,wink0提供的MD5解决方案效果更好。
  2. 请在提交前检查输出。变更是永久性的。