Как я могу сопоставить файлы по размеру файла и переименовать соответственно? - PullRequest
0 голосов
/ 16 августа 2011

У меня есть два каталога изображений с несовпадающими именами, но в основном совпадающие изображения.

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 1, сравнив размер файла (или каким-либо другим способом) с Dir 2. ВПриведенный выше пример img2.jpg будет переименован в image_name.jpg, поскольку оба файла имеют одинаковый размер.

Можете ли вы указать мне правильное направление?

Желательно через приложение (Mac),shell, или php.

Ответы [ 2 ]

3 голосов
/ 16 августа 2011

Может быть, было бы разумнее использовать хеши файлов вместо использования размера файлов?

Вкратце: используя glob (), получить список файлов в dir1, выполнить итерацию, создать md5-hash (md5() + file_get_contents ()), сохранить в массиве, используя хеш в качестве ключа и имя файла в качестве значения.Сделайте то же самое для dir2.

итерируйте массив1, если в файле переименования 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 ] );
 }
}
2 голосов
/ 17 августа 2011

Вот мое решение, которое переименовывает файлы в 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]
    }
}

Сейчас,перейдите в 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. Нет защиты от файлов с таким же размером.Для этого решение MD5, которое предложил wonk0, работает лучше.
  2. Пожалуйста, проверьте вывод перед фиксацией.Изменения постоянны.
...