Страницы

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

понедельник, 6 января 2020 г.

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

#linux


У меня есть Morrowind и куча модов к нему. Я хочу эти моды установить. Как вам известно,
Morrowind писался под винду и моды к нему соответственно тоже, но я использую кроссплатформенный
движок OpenMW, что позволяет нативно запускать игру в линуксе.

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


Ответы

Ответ 1



специализированного средства для исправления подобной эксклюзивной «кривизны», конечно, нет. но такое средство несложно написать на любом подходящем языке программирования, или даже обойтись оболочкой и утилитами из 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 принимает два параметра — «базовый» и «переименовываемый» каталоги.

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

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