3

Мне нужен oneliner, чтобы переименовать все файлы в каталоге из

SomeThing.TXT
NOT A FILE.ogg
sensitive lalala.doc

в

Something.txt
Not A File.ogg
Sensitive Lalala.doc

Другими словами: первые буквы слов являются заглавными, а все остальное - строчными. Это называется начальный регистр или начальные заглавные буквы. Это очень близко к "Заголовку дела". Расширение файла должно быть в нижнем регистре.

Большинство существующих вопросов , кажется, иметь дело только с UPPERCASE.MKV или lowercase.mkv имен файлов, никто не похоже , чтобы покрыть Капитализированное Case.mkv (пример).

Можно использовать все распространенные инструменты, такие как pipe, sed , perl , grep и другие.

4 ответа4

2

Если у вас есть доступ к perl-переименованию (установленному по умолчанию как rename в системах на основе Debian, доступно как perl-rename во многих других), вы можете запустить:

rename  's/.*/lc($&)/e; s/(^| )./uc($&)/ge' *

Объяснение:

Программа rename будет запускать выражение perl для каждого из своих имен входных файлов. Здесь первая операция замещения (s///) заменит все (.*) На себя ($& - это то, что было найдено), но в нижнем регистре (lc($&)). Второй, будет соответствовать каждому символу после пробела или в начале имени файла ((^| )) и заменять его версией в верхнем регистре (uc($&)).

Запустите с флагом -n для проверки без внесения каких-либо изменений:

$ rename -n 's/.*/lc($&)/e; s/ ./uc($&)/ge' *
rename NOT A FILE.ogg not A File.ogg
rename sensitive lalala.doc sensitive Lalala.doc
rename SomeThing.TXT something.txt

Вы также можете использовать цикл оболочки и Perl:

for f in *; do 
    mv "$f" "$(perl -lpe 's/.*/lc($&)/e; s/(^| )./uc($&)/ge' <<<"$f")"
done

Это та же команда, что и при rename , только мы передаем ей каждый файл в каталоге и используем команду подстановки для переименования.

Вы можете легко изменить это, чтобы избежать перезаписи существующих файлов:

for f in *; do 
    target="$(perl -lpe 's/.*/lc($&)/e; s/(^| )./uc($&)/ge' <<<"$f")"; 
    [ -e "$target" ] && 
        echo "File \"$target\" exists, skipping \"$f\"" || 
        mv "$f" "$target"; 
done
1

«Декапитализация» ответил здесь:

for i in *
do
  mv "$i" "$( echo $i | tr '[:upper:]' '[:lower:]')"
done

Капитализация уже ответила здесь:

for i in *
do
  mv "$i" "$( echo $i | sed 's/[ ]*/\u&/g')"
done
1

Я придумал быстрое решение в виде одной строки:

for f in *; do mv -i "$f" "`echo $f | sed -e 's/\(.*\)/\L\1/' -e 's/\( .\)/\U\1/g' -e 's/\(^.\)/\U\1/g'`"; done

Или в удобочитаемой (но немного менее удобной для копирования форме вставки):

for f in *; do 
    mv -i "$f" "`echo $f | 
     sed -e 's/\(.*\)/\L\1/' -e 's/\( .\)/\U\1/g' -e 's/\(^.\)/\U\1/g'`"; 
done

Эта команда использует sed для mv каждого файла в файл с тем же именем, но в котором все символы сначала переводятся в нижний регистр, затем каждая комбинация пробелов, за которыми следует любой символ, превращается в верхний регистр, затем первый символ - в верхний регистр.

Это будет спрашивать перед перезаписью.

Удалите -i если вы хотите, чтобы он автоматически перезаписывал.

1

Это работает на Bash 3.2.57 для Mac OSX

Предварительный просмотр (ничего не меняет):

IFS=$'\n';FOLDER=new;for F in $(ls -1);do EXT="${F##*.}";NAME="${F%.*}";NEW=$(echo "$NAME"| perl -pe 's/[ _-]([A-z0-9])([^ _-]+)/ \U\1\L\2/g');echo "cp '$F' '$FOLDER/$NEW.$EXT'";done

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

IFS=$'\n';FOLDER=new;[ -d $FOLDER ] || mkdir $FOLDER;for F in $(ls -1);do EXT="${F##*.}";NAME="${F%.*}";NEW=$(echo "$NAME"| perl -pe 's/[ _-]([A-z0-9])([^ _-]+)/ \U\1\L\2/g');cp -v "$F" "$FOLDER/$NEW.$EXT";done

Заметки:

  • Не изменит расширение файла.
  • Должны правильно обрабатывать числа.
  • Если у вас есть другие символы, которые вы хотите преобразовать в пробелы, просто добавьте их в класс символов: [ _-]
  • Предотвращает конфликты имен, превращая копию каждого файла в подпапку. Это дает вам возможность отмены. Другой способ справиться с этим - переименовать все файлы, добавив префикс, например _My New File Name.jpg , а затем переименовать все в версии без _ .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .