изменить все дерево каталогов на строчные имена

12

Я работаю над преобразованием веб-сайта. Файлы, поскольку они были связаны и обслуживались с веб-сервера, были нечувствительны к регистру. Но я сделал дамп сайта в моей системе Linux и пишу скрипты для переноса данных. Проблема в том, что я сталкиваюсь с проблемами чувствительности к регистру между строками ссылок на страницах и фактическим регистром слов в файловой системе.

Например, на странице может быть ссылка, как <a href='/subfolder/PageName.asp'>у фактического файла /subfolder/pagename.asp. Аналогично с изображениями - <img src='spacer_sm.gif'>может быть Spacer_Sm.gif.

Поэтому я думаю изменить все каталоги и имена файлов на их строчные эквиваленты для загрузки сайта. Как мне это сделать (и может ли быть лучший способ?)

Даже если есть команды unix, которые имеют переключатели без учета регистра, я использую php, поэтому не все команды файловой системы имеют параметры чувствительности к регистру.

user394
источник
2
Смотрите аналогичный предыдущий вопрос . Я разместил здесь более простой ответ, потому что вопрос немного более конкретен.
Жиль "ТАК - перестань быть злым"

Ответы:

8

Я не знаю, есть ли у твоего unix-аромата rename. Во многих Linux есть, и это часть perl-пакета, если вы ищете репозиторий.

find ./ -depth -exec rename -n 'y/[A-Z]/[a-z]/' {} ";"

Над версией с

rename -n 

на самом деле не выполняет действие, а только печатает, что будет сделано. Вы опускаете -n, ​​чтобы сделать это по-настоящему.

неизвестный пользователь
источник
Какой «язык» или регулярное выражение является 'y/[A-Z]/[a-z]/'частью?
user394
Ну, так как renameэто часть perlпакета, я думаю, Perl, но шаблон используется и в sed, и, возможно, AWKтакже. Я только хорошо знаю sedтишину. Я перевожу yна translateили map, но я не знаю, откуда происходит этот персонаж.
пользователь неизвестен
Должен быть регулярным выражением Perl - Жиль в своем ответе говорит, renameчто это сценарий Perl.
user394
Да, и вы можете использовать регулярные выражения Perl, чтобы изменить имена файлов, что не обязательно означает, что они написаны на Perl, но может быть более интересным вопросом.
пользователь неизвестен
9

Zsh

zmv -o-i '(**/)(*)' '$1${2:l}'

Пояснения: zmvпереименовывает файлы, соответствующие шаблону, в соответствии с заданным текстом замены. -o-iпередает -iопцию каждой mvкоманде под капотом (см. ниже). В тексте замены $1, $2и т. Д., Есть последовательные заключенные в скобки группы в шаблоне. **означает все (под) * каталоги, рекурсивно. Финал (/)- это не группа в скобках, а квалификатор glob, означающий совпадение только с каталогами. ${2:l}преобразует $2в нижний регистр

Perl переименовать

Здесь я использую сценарий переименования Perl, который поставляется вместе с Debian и Ubuntu /usr/bin/prename(как правило, также доступен rename). С bash ≥4 или zsh:

shopt -s globstar  # only in bash
rename 's!/([^/]*/?)$!\L/$1!' **/*

С другими снарядами:

find . -depth -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +

портативный

Рекурсивный:

find . -depth -exec sh -c '
    t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
    [ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

Использование -depthгарантирует, что глубоко вложенные каталоги обрабатываются перед их предками.

Жиль "ТАК - прекрати быть злым"
источник
1

Он не работал со следующей структурой каталогов:

JKL/
deF/
ABC/DEf
ABC/gHi
ghi/jkL

Вот пример, который работает:

for i in `find | sort -r | sed '$d'`; do \
   b=${i%/*}; e=${i##*/}; mv $i $b'/'${e,,}; done

Для объяснения bи eVars:

man bash

Затем используйте следующую последовательность клавиш: /,,Enterbb

Baronsed
источник
0

Принятый ответ не работал для меня, поскольку он пытался изменить все каталоги одновременно. Я нашел другое решение для stackexchange, очень похожее на портативное решение от Gilles выше: от Baramin -
/programming/4268591/unix-rename-files-directories-to-uppercase

Я скопировал это здесь:

find . -depth | \
while read LONG; do
   SHORT=$( basename "$LONG" | tr '[:lower:]' '[:upper:]' )
   DIR=$( dirname "$LONG" )
   if [ "${LONG}" != "${DIR}/${SHORT}"  ]; then
     mv "${LONG}" "${DIR}/${SHORT}"
   fi
done

На что я изменил команду tr на ie: sed s / cat / dog / g

Любая благодарность идет к Baramin по ссылке выше.

JJones
источник