Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: Скрипт для перименования файлов по md5-хешу  (Прочитано 918 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ubu12.04ntu

  • Автор темы
  • Любитель
  • *
  • Сообщений: 91
    • Просмотр профиля
Есть два файла, оба UTF-8, оба по 1,5 млн строк:
md5.csv, содержащий хеши файлов, только нижний регистр символов.
(Нажмите, чтобы показать/скрыть)
names.csv, содержащий имена файлов (без каталогов) в строгом соответствии по строкам их хешам.
(Нажмите, чтобы показать/скрыть)
И есть каталог, содержащий покаталоги с файлами с отфанарными именами.
Нужен скрипт, который даст файлам, совпадающим по хешу с md5.csv имена из names.csv и оставит их в тех же подкаталогах.

Можно ли сделать скрипт под Ubuntu, который сначала из таблицы извлечет встречающиеся файлы, а потом их переименует?
Важно найти наиболее рациональный по времени выполнения задания путь, т.к. процедуру необходимо повторять много раз.
« Последнее редактирование: 23 Март 2016, 14:26:40 от ubu12.04ntu »

Punko

  • Гость
ubu12.04ntu, Мне кажется нет смысла

Цитировать
который сначала из таблицы извлечет встречающиеся файлы, а потом их переименует?

Потому что придётся два раза искать файлы эти - первый раз при проверке есть ли они в системе(а так как это не один каталог, то придётся рекурсивно проверять), а второй раз точно такой же поиск делать для переименования.

Наверно лучше в одном цикле искать файл и при возвращении true сразу его переименовывать. Только надо подумать, как взять нужное новое имя.

А вообще 1.5 млн в тхт это пипец, вы не задумывались о базе данных?


Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Для квалифицированого ответа хотелось бы увидеть пример такой таблицы (10-20 строк). Не совсем понятно про сотни подпапок. Оптимально было бы увидеть тоже пример из 10-15 файлов (расположение с подпапками)
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ubu12.04ntu

  • Автор темы
  • Любитель
  • *
  • Сообщений: 91
    • Просмотр профиля
Немного изменил задачу, помогите пожалуйста.
Скрипты не делал. Знаю только, что есть md5sum.
Надеюсь, что задача быстро решается в несколько строк.

Пользователь решил продолжить мысль [time]23 Март 2016, 15:58:14[/time]:
Может напр. сначала вывести md5 всех файлов сканируемого каталога
find -type f -exec md5sum -b {} + > check_sum.md5а потом сравнивать с md5.csv?
Или сравнение возможно только при одинаковой сортировке хешей в файлах, напр. по алфавиту?
« Последнее редактирование: 23 Март 2016, 18:04:28 от ubu12.04ntu »

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Если не будет проблем с памятью (всё-таки 1,5 млн) можно попробовать через массив
Код: Bash
  1. #!/bin/bash
  2. declare -A  names
  3. while read line
  4. do
  5.     names[${line%       *}]=${line#*    }       #тут <Таб> а не пробелы
  6. done < <(paste md5.csv names.csv)
  7. while read mfile
  8. do
  9.     mdsum=$(md5sum "$mfile")
  10.     mv "$mfile" "${mfile%/*}/${names[${mdsum%% *}]}"
  11. done < <(find <каталог> -type f)
« Последнее редактирование: 24 Март 2016, 00:45:12 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ubu12.04ntu

  • Автор темы
  • Любитель
  • *
  • Сообщений: 91
    • Просмотр профиля
done < <(find </home/user/lib/11/> -type f)Правильно вставил?
Почему тогда
:~/lib$ bash 1.sh
find: `f': Нет такого файла или каталога

Пробовал на мелких файлах, по одной строчке в каждом

Пользователь решил продолжить мысль 23 Март 2016, 23:17:24:
И почему-то появился файл -type в папке lib
« Последнее редактирование: 23 Март 2016, 23:17:24 от ubu12.04ntu »

Punko

  • Гость
ubu12.04ntu,
уберите < >
Это для примера было. Сам путь просто как путь.

Оффлайн ubu12.04ntu

  • Автор темы
  • Любитель
  • *
  • Сообщений: 91
    • Просмотр профиля
<> оттуда убрал
Выдало
mv: «/home/user/lib/11/0.pdf» и «/home/uer/lib/11/0.pdf» - один и тот же файл
А файл не переименовало.

Punko

  • Гость
ubu12.04ntu, ну теперь вопрос к Azure.

Оффлайн ubu12.04ntu

  • Автор темы
  • Любитель
  • *
  • Сообщений: 91
    • Просмотр профиля
Я мало понимаю и мне странно, что в скрипте нет if.
Ведь если md5sum файла равно строке из md5.csv, то тогда переименовать файл в строку из names.csv

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Давайте вставим перед mv echo и посмотрим:
Код: Bash
  1. echo "$mdsum <> ${names[${mdsum% *}]} <> ${mfile%/*}"
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ubu12.04ntu

  • Автор темы
  • Любитель
  • *
  • Сообщений: 91
    • Просмотр профиля
7b2a4d53fde834e801c26a2bab7e0240  /home/user/lib/11/0.pdf <>  <> /home/user/lib/11
mv: «/home/user/lib/11/0.pdf» и «/home/user/lib/11/0.pdf» - один и тот же файл
Запускал так  bash 1.sh
(Нажмите, чтобы показать/скрыть)
« Последнее редактирование: 24 Март 2016, 10:18:24 от ubu12.04ntu »

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Фокус в том, что или имени с таким хэш не существует, nl md5.csv | grep -F '7b2a4d53fde834e801c26a2bab7e0240'или что-то не сработало в плане создания массива имен. paste md5.csv names.csv | headВы пути правильно до файлов  md5.csv names.csv прописали? Там действительно каждое имя/хэш на отдельной строке?
« Последнее редактирование: 24 Март 2016, 10:30:29 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ubu12.04ntu

  • Автор темы
  • Любитель
  • *
  • Сообщений: 91
    • Просмотр профиля
 nl md5.csv | grep -F '7b2a4d53fde834e801c26a2bab7e0240'
     1   7b2a4d53fde834e801c26a2bab7e0240

paste md5.csv names.csv | head
7b2a4d53fde834e801c26a2bab7e0240   Handbook of Clinical Drug Data.rtf

Пробую на 1 файле, точно правильный хеш, файлы вложил.
« Последнее редактирование: 24 Март 2016, 10:54:34 от ubu12.04ntu »

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Код: Bash
  1. #!/bin/bash
  2. declare -A  names
  3. while read line
  4. do
  5.     names[${line%       *}]=${line#*    }       #тут <Таб> а не пробелы
  6. done < <(paste md5.csv names.csv)
  7. echo "${names[@]}" | head
  8. while read mfile
  9. do
  10.     mdsum=$(md5sum "$mfile")
  11.     echo "==${names[${mdsum%% *}]}=="
  12.     mv "$mfile" "${mfile%/*}/${names[${mdsum%% *}]}"
  13. done < <(find <каталог> -type f)
потом строки с echo можно убрать
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

 

Страница сгенерирована за 0.079 секунд. Запросов: 24.