Переименовывать файлы, которые должны быть заглавные, но не влиять на расширения файлов

Хотя содержимое каталога становится недоступным, когда вы монтируете файловую систему сверху, они не теряются. Размонтирование файловой системы должно сделать их видимыми снова. Что-то вроде следующего:

sudo umount ~
7
задан 14 November 2017 в 13:33

12 ответов

Одним из способов достижения этого может быть использование Negative Lookbehind для соответствия только последовательности символов слова-границы слова, когда ему не предшествует буквальный период, например. (

$ ls
alan's file.txt  bar.txt  foo

, тогда

$ rename -n 's/(?<!\.)\b\w*/\u$&/g' *
rename(alan's file.txt, Alan'S File.txt)
rename(bar.txt, Bar.txt)
rename(foo, Foo)

Предполагая, что вы также хотите избежать использования плюрализации s, мы можем изменить это на

$ rename -n 's/(?<![.'\''])\b\w*/\u$&/g' *
rename(alan's file.txt, Alan's File.txt)
rename(bar.txt, Bar.txt)
rename(foo, Foo)

или даже

$ rename -n 's/(?<![[:punct:]])\b\w*/\u$&/g' *
rename(alan's file.txt, Alan's File.txt)
rename(bar.txt, Bar.txt)
rename(foo, Foo)
7
ответ дан 22 May 2018 в 16:57
  • 1
    Отлично! Я буду использовать этот: rename -n 's/(?<![.'\''])\b\w*/\u$&/g' * Спасибо за вашу помощь! – Alan 31 October 2017 в 06:00
  • 2
    @Alan обязательно запустите команду, чтобы убедиться, что она выдает правильные переименования, а затем удалите -n, чтобы фактически переименовать. – NoOneIsHere 31 October 2017 в 08:08
  • 3
    Сделаю - спасибо! – Alan 1 November 2017 в 10:55

Одним из способов достижения этого может быть использование Negative Lookbehind для соответствия только последовательности символов слова-границы слова, когда ему не предшествует буквальный период, например. (

$ ls alan's file.txt bar.txt foo

, тогда

$ rename -n 's/(?<!\.)\b\w*/\u$&/g' * rename(alan's file.txt, Alan'S File.txt) rename(bar.txt, Bar.txt) rename(foo, Foo)

Предполагая, что вы также хотите избежать использования плюрализации s, мы можем изменить это на

$ rename -n 's/(?<![.'\''])\b\w*/\u$&/g' * rename(alan's file.txt, Alan's File.txt) rename(bar.txt, Bar.txt) rename(foo, Foo)

или даже

$ rename -n 's/(?<![[:punct:]])\b\w*/\u$&/g' * rename(alan's file.txt, Alan's File.txt) rename(bar.txt, Bar.txt) rename(foo, Foo)
7
ответ дан 18 July 2018 в 04:14

Одним из способов достижения этого может быть использование Negative Lookbehind для соответствия только последовательности символов слова-границы слова, когда ему не предшествует буквальный период, например. (

$ ls alan's file.txt bar.txt foo

, тогда

$ rename -n 's/(?<!\.)\b\w*/\u$&/g' * rename(alan's file.txt, Alan'S File.txt) rename(bar.txt, Bar.txt) rename(foo, Foo)

Предполагая, что вы также хотите избежать использования плюрализации s, мы можем изменить это на

$ rename -n 's/(?<![.'\''])\b\w*/\u$&/g' * rename(alan's file.txt, Alan's File.txt) rename(bar.txt, Bar.txt) rename(foo, Foo)

или даже

$ rename -n 's/(?<![[:punct:]])\b\w*/\u$&/g' * rename(alan's file.txt, Alan's File.txt) rename(bar.txt, Bar.txt) rename(foo, Foo)
7
ответ дан 24 July 2018 в 18:02

Это будет использовать первую букву каждого слова, кроме последнего расширения:

rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *

Я тестировал эти файлы:

$ ls -1
'a file with a '$'\n''new line.foo'
'a file with spaces.txt'
justonelongfilename.ext
no-extensions-here
this.has.many.extensions.pdf

И он переименует их как:

$ rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *
a file with a 
new line.foo -> A File With A 
New Line.foo
a file with spaces.txt -> A File With Spaces.txt
justonelongfilename.ext -> Justonelongfilename.ext
no-extensions-here -> No-Extensions-Here
this.has.many.extensions.pdf -> This.Has.Many.Extensions.pdf

Хитрость состоит в том, чтобы сначала загладить каждую первую букву, игнорируя расширения, а затем вернуться назад и сделать расширение в нижнем регистре:

s/\b(.+?)\b/\u$1/g;: .+? это не-жадный шаблон, что означает, что он найдет кратчайшее совпадение. Поскольку он привязан границами слов (\b), это найдет все слова (все из-за окончательного g). Затем они заменяются капитализированной (с первой буквой) версией самих себя (\l$1). s/(.+)\.(.)/$1\.\l$2/: .+ жадный, поэтому он найдет максимально возможное совпадение. Это означает, что самая длинная строка до окончательного ., после которой будет расширение (если оно есть). Мы заменяем совпадение всем до расширения ($1), a . и продолжением с первой буквой нижней обложки (\l$2).

Рекурсия также достаточно проста. Если ваша оболочка bash (если вы этого не знаете, возможно, это так), вы можете использовать опцию globstar, которая делает ** совпадением 0 или более подкаталогов:

shopt -s globstar

Теперь запустите переименование (это будет также работать с любыми файлами в вашем текущем каталоге):

rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' **

Чтобы ограничить его только файлами или каталогами с расширениями, используйте **/*.* вместо **.

В качестве альтернативы используйте find:

find /path/to/dir -exec rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' {} +

И, чтобы ограничить эти файлы и каталоги с расширением:

find /path/to/dir -name '*.*' -exec rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' {} +

Обратите внимание, что все из этих решений будет весело переименовывать каталоги, а также файлы. Если вы этого не хотите, будьте осторожны, когда вы скажете, чтобы он рекурсировал, или дайте ему более конкретный шаблон, например *.txt.

все эти решения будет весело переименовывать каталоги, а также файлы . -n заставляет rename просто печатать, что он будет делать, а на самом деле ничего не делать. Полезно для тестирования.

5
ответ дан 22 May 2018 в 16:57
  • 1
    Умный ход, заглавные буквы всех первых букв, затем сглаживание расширения. Добавили +1 – Sergiy Kolodyazhnyy 31 October 2017 в 03:57
  • 2
    Хантердон: Я только что испытал rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *, и он почти работает, но он также капитализирует притяжательные Alan's. Похоже, у SteelDriver есть ответ ниже с rename -n 's/(?<![.'\''])\b\w*/\u$&/g' * Спасибо за помощь! – Alan 31 October 2017 в 05:59

Наиболее разумным способом было бы занятие всех «слов» (с использованием границы слова \b и обращение через $1 к любому первому символу), включая расширение, но затем в нижнем регистре самого расширения:

[ f1]

Обратите внимание, что это не работает для имени файла с символами подчеркивания, то есть границы слова «слово» рассматриваются в пробелах (вкладки, пробелы, строки новой строки, которые, надеюсь, не должны быть в имени файла).

[d2 ] Обратите внимание на использование prename для переносимости на ksh, где rename - фактически встроенная команда, а не автономный исполняемый файл perl.

4
ответ дан 22 May 2018 в 16:57
  • 1
    Привет Сергий. Если я это сделаю, мне нужно будет перечислять все возможные расширения в массиве в конце команды? Кроме того, он sems переименовывает alan's file.txt в качестве Alan's file.txt (не использует второе слово). – Alan 31 October 2017 в 03:17
  • 2
    @Alan ах, так что вы хотели все слова имени файла заглавные буквы? Можете ли вы отредактировать исходное сообщение, чтобы включить эту информацию? Что касается расширений - да, это было бы правильно, «массив». всех возможных комбинаций. – Sergiy Kolodyazhnyy 31 October 2017 в 03:22
  • 3
    Привет, Сергей. Теперь он читает rename files with first letter of each word being capitalised, что все в порядке? В терминах массива я мог бы сделать *.*? – Alan 31 October 2017 в 03:26
  • 4
    @Alan yeah, *.* будет в порядке, если в имени файла будет только один ., т. Е. Нет foo.bar.txt. Спасибо за редактирование, кстати, я буду работать над редактированием моего ответа сейчас – Sergiy Kolodyazhnyy 31 October 2017 в 03:37
  • 5
    @Sergiy *.* должен соответствовать всем не скрытым файлам с расширением, включая foo.bar.txt, поэтому *.* должен работать нормально. Не нужно указывать список расширений. – terdon♦ 31 October 2017 в 03:49

Просто используйте rename 's/\b(\w)/\u$1/' * БЕЗ флага g. Флаг g означает «global = сделать это несколько раз». Вы делаете первый раз в имени файла, и вы не хотите делать заглавные буквы во второй раз?

1
ответ дан 22 May 2018 в 16:57
  • 1
    Привет V-Mark - я пробовал это, но он переименовывает «zz alan.txt» в «Alan's file.txt» (он использует только первое слово, но не другие слова. Они хотят, чтобы каждое слово было заглавным). – Alan 31 October 2017 в 03:15
  • 2
    @Alan это было бы намного легче понять, если бы вы включили некоторые примеры в свой вопрос и то, что вы хотели бы, чтобы их переименовали. Пожалуйста, обязательно укажите, что ваш комментарий здесь гласит, что zz alan.txt был переименован в Alan's file.txt, что маловероятно :) – terdon♦ 31 October 2017 в 03:35
  • 3
    @Alan Что делать, если вы оставите исходное имя переименования, но сделайте расширение в нижнем регистре с помощью rename 's/(.*)\.(\w)(.*)/$1.\l$2$3/' *. Это делает слово до последнего периода в нижнем регистре. Итак, от Qwe.Asd.Zxc до Qwe.Asd.zxc ` – V-Mark 31 October 2017 в 03:48
  • 4
    ... и вы можете поместить эти переименования вместе ... – V-Mark 31 October 2017 в 03:56
  • 5
    Привет V-Mark - Не знаю, как это отличается от того, что я делаю сейчас (хотя, вероятно, более эффективно). Я все равно буду выполнять две команды? – Alan 31 October 2017 в 05:51

Наиболее разумным способом было бы занятие всех «слов» (с использованием границы слова \b и обращение через $1 к любому первому символу), включая расширение, но затем в нижнем регистре самого расширения:

$ prename -nv 's/\b(.)/\u$1/g;s/^(.*)\.(.*)/$1.\l$2/' * another filename trispaced.txt renamed as Another Filename Trispaced.txt filename_with_underschore.txt renamed as Filename_with_underschore.txt one filename.txt renamed as One Filename.txt

Обратите внимание, что это не работает для имени файла с символами подчеркивания, то есть границы слова «слово» рассматриваются в пробелах (вкладки, пробелы, строки новой строки, которые, надеюсь, не должны быть в имени файла).

Обратите внимание на использование prename для переносимости на ksh, где rename - фактически встроенная команда, а не автономный исполняемый файл perl.

4
ответ дан 18 July 2018 в 04:14

Это будет использовать первую букву каждого слова, кроме последнего расширения:

rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *

Я тестировал эти файлы:

$ ls -1 'a file with a '$'\n''new line.foo' 'a file with spaces.txt' justonelongfilename.ext no-extensions-here this.has.many.extensions.pdf

И он переименует их как:

$ rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' * a file with a new line.foo -> A File With A New Line.foo a file with spaces.txt -> A File With Spaces.txt justonelongfilename.ext -> Justonelongfilename.ext no-extensions-here -> No-Extensions-Here this.has.many.extensions.pdf -> This.Has.Many.Extensions.pdf

Хитрость состоит в том, чтобы сначала загладить каждую первую букву, игнорируя расширения, а затем вернуться назад и сделать расширение в нижнем регистре:

s/\b(.+?)\b/\u$1/g;: .+? это не-жадный шаблон, что означает, что он найдет кратчайшее совпадение. Поскольку он привязан границами слов (\b), это найдет все слова (все из-за окончательного g). Затем они заменяются капитализированной (с первой буквой) версией самих себя (\l$1). s/(.+)\.(.)/$1\.\l$2/: .+ жадный, поэтому он найдет максимально возможное совпадение. Это означает, что самая длинная строка до окончательного ., после которой будет расширение (если оно есть). Мы заменяем совпадение всем до расширения ($1), a . и продолжением с первой буквой нижней обложки (\l$2).

Рекурсия также достаточно проста. Если ваша оболочка bash (если вы этого не знаете, возможно, это так), вы можете использовать опцию globstar, которая делает ** совпадением 0 или более подкаталогов:

shopt -s globstar

Теперь запустите переименование (это будет также работать с любыми файлами в вашем текущем каталоге):

rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' **

Чтобы ограничить его только файлами или каталогами с расширениями, используйте **/*.* вместо **.

В качестве альтернативы используйте find:

find /path/to/dir -exec rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' {} +

И, чтобы ограничить эти файлы и каталоги с расширением:

find /path/to/dir -name '*.*' -exec rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' {} +

Обратите внимание, что все из этих решений будет весело переименовывать каталоги, а также файлы. Если вы этого не хотите, будьте осторожны, когда вы скажете, чтобы он рекурсировал, или дайте ему более конкретный шаблон, например *.txt.

все эти решения будет весело переименовывать каталоги, а также файлы . -n заставляет rename просто печатать, что он будет делать, а на самом деле ничего не делать. Полезно для тестирования.

5
ответ дан 18 July 2018 в 04:14

Просто используйте rename 's/\b(\w)/\u$1/' * БЕЗ флага g. Флаг g означает «global = сделать это несколько раз». Вы делаете первый раз в имени файла, и вы не хотите делать заглавные буквы во второй раз?

1
ответ дан 18 July 2018 в 04:14

Наиболее разумным способом было бы занятие всех «слов» (с использованием границы слова \b и обращение через $1 к любому первому символу), включая расширение, но затем в нижнем регистре самого расширения:

$ prename -nv 's/\b(.)/\u$1/g;s/^(.*)\.(.*)/$1.\l$2/' * another filename trispaced.txt renamed as Another Filename Trispaced.txt filename_with_underschore.txt renamed as Filename_with_underschore.txt one filename.txt renamed as One Filename.txt

Обратите внимание, что это не работает для имени файла с символами подчеркивания, то есть границы слова «слово» рассматриваются в пробелах (вкладки, пробелы, строки новой строки, которые, надеюсь, не должны быть в имени файла).

Обратите внимание на использование prename для переносимости на ksh, где rename - фактически встроенная команда, а не автономный исполняемый файл perl.

4
ответ дан 24 July 2018 в 18:02
  • 1
    Привет Сергий. Если я это сделаю, мне нужно будет перечислять все возможные расширения в массиве в конце команды? Кроме того, он sems переименовывает alan's file.txt в качестве Alan's file.txt (не использует второе слово). – Alan 31 October 2017 в 03:17
  • 2
    @Alan ах, так что вы хотели все слова имени файла заглавные буквы? Можете ли вы отредактировать исходное сообщение, чтобы включить эту информацию? Что касается расширений - да, это было бы правильно, «массив». всех возможных комбинаций. – Sergiy Kolodyazhnyy 31 October 2017 в 03:22
  • 3
    Привет, Сергей. Теперь он читает rename files with first letter of each word being capitalised, что все в порядке? В терминах массива я мог бы сделать *.*? – Alan 31 October 2017 в 03:26
  • 4
    @Alan yeah, *.* будет в порядке, если в имени файла будет только один ., т. Е. Нет foo.bar.txt. Спасибо за редактирование, кстати, я буду работать над редактированием моего ответа сейчас – Sergiy Kolodyazhnyy 31 October 2017 в 03:37
  • 5
    @Sergiy *.* должен соответствовать всем не скрытым файлам с расширением, включая foo.bar.txt, поэтому *.* должен работать нормально. Не нужно указывать список расширений. – terdon♦ 31 October 2017 в 03:49

Это будет использовать первую букву каждого слова, кроме последнего расширения:

rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *

Я тестировал эти файлы:

$ ls -1 'a file with a '$'\n''new line.foo' 'a file with spaces.txt' justonelongfilename.ext no-extensions-here this.has.many.extensions.pdf

И он переименует их как:

$ rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' * a file with a new line.foo -> A File With A New Line.foo a file with spaces.txt -> A File With Spaces.txt justonelongfilename.ext -> Justonelongfilename.ext no-extensions-here -> No-Extensions-Here this.has.many.extensions.pdf -> This.Has.Many.Extensions.pdf

Хитрость состоит в том, чтобы сначала загладить каждую первую букву, игнорируя расширения, а затем вернуться назад и сделать расширение в нижнем регистре:

s/\b(.+?)\b/\u$1/g;: .+? это не-жадный шаблон, что означает, что он найдет кратчайшее совпадение. Поскольку он привязан границами слов (\b), это найдет все слова (все из-за окончательного g). Затем они заменяются капитализированной (с первой буквой) версией самих себя (\l$1). s/(.+)\.(.)/$1\.\l$2/: .+ жадный, поэтому он найдет максимально возможное совпадение. Это означает, что самая длинная строка до окончательного ., после которой будет расширение (если оно есть). Мы заменяем совпадение всем до расширения ($1), a . и продолжением с первой буквой нижней обложки (\l$2).

Рекурсия также достаточно проста. Если ваша оболочка bash (если вы этого не знаете, возможно, это так), вы можете использовать опцию globstar, которая делает ** совпадением 0 или более подкаталогов:

shopt -s globstar

Теперь запустите переименование (это будет также работать с любыми файлами в вашем текущем каталоге):

rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' **

Чтобы ограничить его только файлами или каталогами с расширениями, используйте **/*.* вместо **.

В качестве альтернативы используйте find:

find /path/to/dir -exec rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' {} +

И, чтобы ограничить эти файлы и каталоги с расширением:

find /path/to/dir -name '*.*' -exec rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' {} +

Обратите внимание, что все из этих решений будет весело переименовывать каталоги, а также файлы. Если вы этого не хотите, будьте осторожны, когда вы скажете, чтобы он рекурсировал, или дайте ему более конкретный шаблон, например *.txt.

все эти решения будет весело переименовывать каталоги, а также файлы . -n заставляет rename просто печатать, что он будет делать, а на самом деле ничего не делать. Полезно для тестирования.

5
ответ дан 24 July 2018 в 18:02
  • 1
    Умный ход, заглавные буквы всех первых букв, затем сглаживание расширения. Добавили +1 – Sergiy Kolodyazhnyy 31 October 2017 в 03:57
  • 2
    Хантердон: Я только что испытал rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *, и он почти работает, но он также капитализирует притяжательные Alan's. Похоже, у SteelDriver есть ответ ниже с rename -n 's/(?<![.'\''])\b\w*/\u$&/g' * Спасибо за помощь! – Alan 31 October 2017 в 05:59

Просто используйте rename 's/\b(\w)/\u$1/' * БЕЗ флага g. Флаг g означает «global = сделать это несколько раз». Вы делаете первый раз в имени файла, и вы не хотите делать заглавные буквы во второй раз?

1
ответ дан 24 July 2018 в 18:02
  • 1
    Привет V-Mark - я пробовал это, но он переименовывает «zz alan.txt» в «Alan's file.txt» (он использует только первое слово, но не другие слова. Они хотят, чтобы каждое слово было заглавным). – Alan 31 October 2017 в 03:15
  • 2
    @Alan это было бы намного легче понять, если бы вы включили некоторые примеры в свой вопрос и то, что вы хотели бы, чтобы их переименовали. Пожалуйста, обязательно укажите, что ваш комментарий здесь гласит, что zz alan.txt был переименован в Alan's file.txt, что маловероятно :) – terdon♦ 31 October 2017 в 03:35
  • 3
    @Alan Что делать, если вы оставите исходное имя переименования, но сделайте расширение в нижнем регистре с помощью rename 's/(.*)\.(\w)(.*)/$1.\l$2$3/' *. Это делает слово до последнего периода в нижнем регистре. Итак, от Qwe.Asd.Zxc до Qwe.Asd.zxc ` – V-Mark 31 October 2017 в 03:48
  • 4
    ... и вы можете поместить эти переименования вместе ... – V-Mark 31 October 2017 в 03:56
  • 5
    Привет V-Mark - Не знаю, как это отличается от того, что я делаю сейчас (хотя, вероятно, более эффективно). Я все равно буду выполнять две команды? – Alan 31 October 2017 в 05:51

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

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