Страницы

Поиск по вопросам

среда, 13 февраля 2019 г.

Как копировать файлы с заменой в Linux тем же методом, что и в Windows? (без учёта регистра)

У меня есть Morrowind и куча модов к нему. Я хочу эти моды установить. Как вам известно, Morrowind писался под винду и моды к нему соответственно тоже, но я использую кроссплатформенный движок OpenMW, что позволяет нативно запускать игру в линуксе.
Так вот в чём моя проблема: установка модов обычно сводится к распаковке файлов из архива мода в директорию игры с заменой. Беда в том, что если оригинальная папка называется "Sound", а в архиве находится папка "sound", то никакой замены не произойдёт (аналогично и с файлами)! У меня просто будет 2 разных папки/файла, потому что линукс чувствителен к регистру. В итоге мод установится криво (а таких модов очень много и вручную я всё проследить не могу).


Ответ

специализированного средства для исправления подобной эксклюзивной «кривизны», конечно, нет.
но такое средство несложно написать на любом подходящем языке программирования, или даже обойтись оболочкой и утилитами из gnu/coreutils

например, у нас есть «базовый» каталог 1
$ tree 1 1 └── Sound ├── File └── File2
и есть распакованный (или любым другим образом полученный) каталог 2, в котором есть некоторые файлы/каталоги, отличающиеся от аналогичных файлов/каталогов из каталога 1 регистром имени:
$ tree 2 2 └── sound ├── file └── file3
фактически, нам надо привести имена таких файлов/каталогов к тому же регистру, что и в каталоге 1. т.е., sound/file переименовать в sound/File и sound переименовать в Sound
сохраним имя «базового» каталога в переменной base, а имя «переименовываемого» каталога — в ren
$ base=1 ren=2 составим список файлов/каталогов, совпадающих при преобразовании их в нижний регистр (с таким же успехом можно было и в верхний):
$ comm -1 -2 \ <(cd "$base"; find -mindepth 1 | tr '[:upper:]' '[:lower:]' | sort) \ <(cd "$ren"; find -mindepth 1 | tr '[:upper:]' '[:lower:]' | sort)
получаем:
./sound ./sound/file в цикле будем читать имена, находить исходные (без преобразования регистра) имена, сравнивать их и, если не совпадают, переименовывать и сообщать об этом:
$ comm -1 -2 \ <(cd "$base"; find -mindepth 1 | tr '[:upper:]' '[:lower:]' | sort) \ <(cd "$ren"; find -mindepth 1 | tr '[:upper:]' '[:lower:]' | sort) | \ while read n; do \ c1=$(cd "$base"; find -iwholename "$n"); \ c2=$(cd "$ren"; find -iwholename "$n"); \ if [[ "$c1" != "$c2" ]]; then \ echo "переименовываем $ren/$c2 в $ren/$c1"; \ mv "$ren/$c2" "$ren/$c1"; \ fi; \ done
получаем:
переименовываем 2/./sound в 2/./Sound переименовываем 2/./Sound/file в 2/./Sound/File
а внутри каталога 2 — имена в нужном регистре:
$ tree 2 2 └── Sound ├── File └── file3

итоговый скрипт:
#!/bin/bash base=$1 ren=$2 comm -1 -2 \ <(cd "$base"; find -mindepth 1 | tr '[:upper:]' '[:lower:]' | sort) \ <(cd "$ren"; find -mindepth 1 | tr '[:upper:]' '[:lower:]' | sort) | \ while read n; do c1=$(cd "$base"; find -iwholename "$n") c2=$(cd "$ren"; find -iwholename "$n") if [[ "$c1" != "$c2" ]]; then echo "переименовываем $ren/$c2 в $ren/$c1" mv "$ren/$c2" "$ren/$c1" fi done
принимает два параметра — «базовый» и «переименовываемый» каталоги.

Комментариев нет:

Отправить комментарий