в нижнем регистре ко всем файлам в каталоге, ожидающим отменить его в какой-то момент

Вы можете использовать apache userdir для этого. См. Это сообщение для деталей: Apache, символически привязанный к домашнему каталогу - ошибки разрешения

1
задан 12 October 2014 в 06:34

2 ответа

Переименование достаточно просто с небольшим преобразованием с помощью rename. Следующее - инертное (удалите флаг -n, чтобы заставить его делать что-то), и он скажет вам, что он делает:

rename 'tr/A-Z/a-z/' -vn * 

Однако, если вы хотите построить это в обратимом скрипте, вы нужно сделать немного больше:

rename 'tr/A-Z/a-z/' -vn * | sed 's/ renamed as /#/' | awk -F'#' '{print "mv '\''" $2 "'\'' '\''" $1 "'\''"}' > reverse.sh

Если вам нужно изменить список файлов, входящих в это (например, рекурсивный), вы можете либо называть имена в rename: [ ! d3]

find | rename ...

Или используйте некоторые параметры Bash для рекурсивного воспроизведения:

shopt -s globstar
rename ... ** *
1
ответ дан 24 May 2018 в 02:57
  • 1
    Это здорово, но я думаю, что проблема в том, что он переименовывает папку, прежде чем переименовывать ее содержимое, потому что я продолжаю получать «никаких таких файлов или каталогов». для всех файлов в подкаталогах. Сами подкаталоги меняют имена, но контент не – CarrKnight 12 October 2014 в 07:08
  • 2
    Один потенциальный риск с вашим awk-скриптом: имена файлов могут содержать одинарные кавычки. – glenn jackman 12 October 2014 в 21:06
  • 3
    @CarrKnight, если вы используете find, используйте опцию -depth. – muru 12 October 2014 в 21:47
#!/bin/bash

IFS=$'\n'
WORKING_PATH=$(pwd $1)

RESTORE_FILENAME="$WORKING_PATH/restore_case.sh"

echo "#!/bin/bash" > "$RESTORE_FILENAME"
chmod a+x "$RESTORE_FILENAME"


for FILEPATH in $(find . -type f)
do
    FILENAME="${FILEPATH##*/}"
    LOWER_FILE="${FILEPATH::-${#FILENAME}}${FILENAME,,}"

    if [ "$LOWER_FILE" != "$FILEPATH" ]; then
        echo moving "$FILEPATH" to "$LOWER_FILE"
        echo mv \""$LOWER_FILE"\" \""$FILEPATH"\" >> "$RESTORE_FILENAME"_files
        mv "$FILEPATH" "$LOWER_FILE"
    fi
done

touch "$RESTORE_FILENAME"_dirs

for DIRPATH in $(find . -type d -printf "%d%p\n"|sort -nr)
do
    DIRPATH=${DIRPATH:1}
    DIRNAME="${DIRPATH##*/}"
    LOWER_DIRPATH="${DIRPATH::-${#DIRNAME}}${DIRNAME,,}"
    if [ "$LOWER_DIRPATH" != "$DIRPATH" ]; then
        echo moving "$DIRPATH" to "$LOWER_DIRPATH"
        echo -e "mv \""$LOWER_DIRPATH"\" \""$DIRPATH"\"\n$(cat "$RESTORE_FILENAME"_dirs)" > "$RESTORE_FILENAME"_dirs
        mv "$DIRPATH" "$LOWER_DIRPATH"
    fi
done

cat "$RESTORE_FILENAME"_dirs "$RESTORE_FILENAME"_files >> "$RESTORE_FILENAME"
rm "$RESTORE_FILENAME"_dirs "$RESTORE_FILENAME"_files

echo rm '$0' >> "$RESTORE_FILENAME"

дольше, немного грязно, но более точно, также не делает ненужных mv

0
ответ дан 24 May 2018 в 02:57
  • 1
    Вы должны использовать printf "%q", как принятый ответ. echo "mv \"...." легко ломается. – muru 27 June 2017 в 04:36
  • 2
    Анализ вывода IFS=$'\n'; find уязвим для имен файлов, содержащих новые строки. Лучше использовать find . -type f -print0 | while read -d '' FILEPATH ... или shopt -s globstar; for FILEPATH in **/* .... – wjandrea 27 June 2017 в 04:49
  • 3
    да, реализация немного грязная, но логика намного точнее (что важно для меня), а также этот уровень «уязвимости». для меня достаточно. У меня нет времени, чтобы углубиться в bash-скриптинг, просто выполнил требуемую задачу для меня и подумал, что кто-то может найти ее полезной (принятый ответ не подходит для моего случая) – sss123next 27 June 2017 в 21:26

Другие вопросы по тегам:

Похожие вопросы: