Как переименовать загруженное приложение с помощью bash в нижний регистр? [Дубликат]

138
задан dsm 30 September 2008 в 13:21
поделиться

22 ответа

Краткая версия с использованием команды "rename".

find my_root_dir -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

Это позволяет избежать проблем с переименованием каталогов перед файлами и попыткой перемещения файлов в несуществующие каталоги (например, "A/A" в "a/a" ).

Или более подробная версия без использования "rename".

for SRC in `find my_root_dir -depth`
do
    DST=`dirname "${SRC}"`/`basename "${SRC}" | tr '[A-Z]' '[a-z]'`
    if [ "${SRC}" != "${DST}" ]
    then
        [ ! -e "${DST}" ] && mv -T "${SRC}" "${DST}" || echo "${SRC} was not renamed"
    fi
done

P. S.

Последний позволяет большую гибкость с командой перемещения (например, "svn mv").

153
ответ дан Alex B 27 August 2018 в 05:54
поделиться
  • 1
    с помощью переименования можно сделать этот путь, а также переименовать 'y / A-Z / a-z /' * – Tzury Bar Yochay 11 October 2009 в 08:07
  • 2
    Остерегайтесь, обе версии не будут работать в файловой системе, не учитывающей регистр. В моем случае я заменил then -замкнутую строку на (mv "${SRC}" "${DST}.renametmp" && mv "${DST}.renametmp" "${DST}") || echo "${SRC} was not renamed". – Lloeki 20 April 2011 в 17:21
  • 3
    Второй подход не работал корректно для меня с файлами, содержащими пробелы (context: linux, bash). – dim 29 June 2011 в 17:34
  • 4
    Используя последнюю версию переименования, никакого регулярного выражения не требуется. Полная команда становится find my_root_dir -depth -exec rename -c {} \;. Добавьте -f, чтобы переименовать, если вы находитесь в файловой системе без учета регистра (например, Mac) – Javache 14 August 2011 в 15:24
  • 5
    1. не работает с современной версией rename ... – Малъ Скрылевъ 9 April 2016 в 09:03

Используя фиксатор файла Larry Wall

$op = shift or die $help;
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}

, он прост, как

find | fix 'tr/A-Z/a-z/'

(где fix - это, конечно, скрипт выше)

4
ответ дан agnul 27 August 2018 в 05:54
поделиться

С MacOS,

Установите пакет rename,

brew install rename

Use,

find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"                       

Эта команда найдет все файлы с *.py и преобразует имена файлов в нижний регистр.

`f` - forces a rename

Пример вывода,

$ find . -iname "*.py" -type f
./sample/Sample_File.py
./sample_file.py
$ find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"
$ find . -iname "*.py" -type f
./sample/sample_file.py
./sample_file.py
1
ответ дан akilesh raj 27 August 2018 в 05:54
поделиться

Это работает, если у вас уже есть или настроить команду переименования (например, через установку Brew на Mac):

rename --lower-case --force somedir/*
8
ответ дан alemol 27 August 2018 в 05:54
поделиться
  • 1
    ... если вы сначала настроили переименование, например. через brew install rename – pduersteler 20 November 2015 в 10:15
  • 2
    переименовать 'y / A-Z / a-z /' * – Stephen 18 February 2017 в 11:53
  • 3
    --lower-case? К сожалению, это не так в Arch Linux. – w17t 22 June 2017 в 21:14
  • 4
    rename не является встроенным bash. Это внешняя утилита, и синтаксис будет отличаться в зависимости от установленной вами версии. Этот ответ недостаточен в качестве переносного решения "для всех ОС на основе UNIX" как заявлено. – Corey Goldberg 25 November 2017 в 14:18
  • 5

по-прежнему мне очень нравится

rename 'y/A-Z/a-z/' *

На нечувствительных к регистру файловых системах, таких как HFS + OS X, вам нужно добавить флаг -f

rename -f 'y/A-Z/a-z/' *
215
ответ дан Antzi 27 August 2018 в 05:54
поделиться
  • 1
    +1. Этот точный пример приведен на странице руководства для переименования. – Drew Noakes 14 February 2013 в 22:07
  • 2
    linux.icydog.net/rename.php : The renaming utility that comes by default with Ubuntu is a Perl program sometimes called prename – sleepsort 8 May 2013 в 16:19
  • 3
    Спасибо, я использовал его таким образом. $ Find | xargs переименовать 'y / A-Z / a-z /' * – Rashi 26 October 2013 в 07:36
  • 4
    Это предполагает, что вы переименовали perls, что не всегда. например на моем debian переименовании полностью отличается – Krzysztof Krasoń 17 March 2015 в 09:37
  • 5
    В Arch, программа называется perl-rename (и предоставляется пакетом с тем же именем) – jaymmer 13 November 2015 в 05:20

Не переносится, только Zsh, но довольно кратким.

Сначала убедитесь, что загружен zmv.

autoload -U zmv

Кроме того, убедитесь, что extendedglob включен:

setopt extendedglob

Затем используйте:

zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'

Для рекурсивно строчных файлов и каталогов, где имя не указано CVS .

1
ответ дан benjwadams 27 August 2018 в 05:54
поделиться

Slugify Rename (regex)

Не совсем то, что запросил OP, но то, что я надеялся найти на этой странице:

Версия «slugify» для переименования файлов они похожи на URL-адреса (т. е. включают только буквенно-цифровые, точки и тире):

rename "s/[^a-zA-Z0-9\.]+/-/g" filename
0
ответ дан cwd 27 August 2018 в 05:54
поделиться
  • 1
    & quot; не точно & quot ;? это вовсе не то, о чем попросил ОП – Corey Goldberg 25 November 2017 в 14:28

Мне нужно было сделать это на установке cygwin в Windows 7 и обнаружил, что у меня возникли синтаксические ошибки с предложениями выше, которые я пробовал (хотя я, возможно, пропустил рабочий параметр), однако это решение прямо из ubutu форумы выработали из can: -)

ls | while read upName; do loName=`echo "${upName}" | tr '[:upper:]' '[:lower:]'`; mv "$upName" "$loName"; done

(nb Я раньше заменил пробелы символами подчеркивания, используя

for f in *\ *; do mv "$f" "${f// /_}"; done
0
ответ дан fedorqui 27 August 2018 в 05:54
поделиться

Просто попробуйте следовать, если вам не нужно заботиться об эффективности.

zip -r foo.zip foo/*
unzip -LL foo.zip
59
ответ дан Ginhing 27 August 2018 в 05:54
поделиться
  • 1
    Вау, это довольно неэффективный способ. – Artjom B. 31 August 2014 в 10:24
  • 2
    Предполагая, что вычислительная эффективность обычно не является проблемой, когда вам нужно переименовывать файлы в каталоге ... Я думаю, что это, вероятно, самое творчески простое решение в этой теме. На самом деле это тривиальное не должно быть таким сложным, как демонстрируют принятые ответы, и это обходное решение гораздо более пропорционально количеству мысли, которое я хочу инвестировать в такую ​​операцию. +1000 – Peter M. Elias 18 April 2015 в 20:20
  • 3
    @peter, более того, он работает! Я попытался использовать другие более сложные ответы, и по какой-либо причине, которая была выше моей готовности отлаживать, они просто не работали. этот простой работает как шарм! – JHixson 8 October 2015 в 08:44
  • 4
    Вы можете ускорить его с помощью -0 (это переключатель «zero», без сжатия), zip -0 -r foo.zip foo/. – Johnny Baloney 16 February 2016 в 20:29
  • 5
    Мне пришлось изменить более 50 000 имен файлов в разных структурах каталогов. Первоначальный принятый ответ выполнил едва ли 10% работы за 2 минуты, когда это при сжатии -0 было почти мгновенным! – Peon 1 February 2017 в 14:14

В исходном вопросе просили игнорировать каталоги SVN и CVS, что можно сделать, добавив -prune к команде find. Например, игнорировать CVS:

find . -name CVS -prune -o -exec mv '{}' `echo {} | tr '[A-Z]' '[a-z]'` \; -print

[edit] Я попробовал это, и вложение перевода в нижний регистр внутри поиска не работало по причинам, которые я действительно не понимаю. Итак, измените это на:

$> cat > tolower
#!/bin/bash
mv $1 `echo $1 | tr '[:upper:]' '[:lower:]'`
^D
$> chmod u+x tolower 
$> find . -name CVS -prune -o -exec tolower '{}'  \;

Ian

4
ответ дан Ian Dickinson 27 August 2018 в 05:54
поделиться

В этой ситуации я бы выбрал python, чтобы избежать оптимизма, предполагая пути без пробелов или косых черт. Я также обнаружил, что python2 имеет тенденцию устанавливаться в большем количестве мест, чем rename.

#!/usr/bin/env python2
import sys, os

def rename_dir(directory):
  print('DEBUG: rename('+directory+')')
  # rename current directory if needed
  os.rename(directory, directory.lower())
  directory = directory.lower()

  # rename children
  for fn in os.listdir(directory):
    path = os.path.join(directory, fn)
    os.rename(path, path.lower())
    path = path.lower()

    # rename children within, if this child is a directory
    if os.path.isdir(path):
        rename_dir(path)

# run program, using the first argument passed to this python script as the name of the folder
rename_dir(sys.argv[1])
1
ответ дан John Foley 27 August 2018 в 05:54
поделиться
  • 1
    Поговорите о том, чтобы сделать это сложным ... просто сделайте .. rename 'y / A-Z / a-z /' * – Stephen 18 February 2017 в 11:53
  • 2
    @Stephen, предполагается, что у вас есть доступ администратора для установки переименования. Мне часто приходится передавать данные в системы, на которых у меня нет возможности устанавливать другое программное обеспечение. В недавнем Ubuntus это устанавливается только в том случае, если присутствует perl. – John Foley 20 February 2017 в 16:00

В OSX mv -f показывает ошибку «того же файла», поэтому я дважды переименовываю

for i in `find . -name "*" -type f |grep -e "[A-Z]"`; do j=`echo $i | tr '[A-Z]' '[a-z]' | sed s/\-1$//`; mv $i $i-1; mv $i-1 $j; done
1
ответ дан Jonghee Park 27 August 2018 в 05:54
поделиться
for f in `find -depth`; do mv ${f} ${f,,} ; done

find -depth печатает каждый файл и каталог с содержимым каталога, напечатанным перед самим каталогом. ${f,,} уменьшает имя файла.

1
ответ дан jpaugh 27 August 2018 в 05:54
поделиться
  • 1
    Это не сработает: он переименовывает каталог, прежде чем он будет работать с содержимым, так что последующая попытка содержимого не будет выполнена. – Prune 22 February 2016 в 20:07
  • 2
    Добавление -depth исправляет это! Это действительно быстрое решение, но, конечно, без использования опции -print0 для поиска, это не самый надежный – jpaugh 25 February 2016 в 22:08

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

  1. Что произойдет, если у вас есть два или более имен на одном уровне иерархии путей, которые различаются только по одному случаю, например ABCdef, abcDEF и aBcDeF? Должен ли переименовать сценарий прерывания или просто предупредить и продолжить?
  2. Как вы определяете строчные буквы для имен не для US-ASCII? Если такие имена могут присутствовать, следует ли сначала выполнить проверку и исключить проход?
  3. Если вы выполняете операцию переименования в рабочих копиях CVS или SVN, вы можете повредить рабочую копию, если вы измените случай на имена файлов или каталогов. Если скрипт также находит и настраивает внутренние административные файлы, такие как .svn / entries или CVS / Entries?
2
ответ дан Mihai Limbășan 27 August 2018 в 05:54
поделиться

Большинство вышеперечисленных ответов опасны, поскольку они не обрабатывают имена, содержащие нечетные символы. Ваша самая безопасная ставка для такого рода вещей - использовать опцию find -print0, которая прекратит имена файлов с помощью ascii NUL вместо\n. Здесь я отправляю этот скрипт, который только изменяет файлы, а не имена каталогов, чтобы не путать поиск.

find .  -type f -print0 | xargs -0n 1 bash -c \
's=$(dirname "$0")/$(basename "$0"); 
d=$(dirname "$0")/$(basename "$0"|tr "[A-Z]" "[a-z]"); mv -f "$s" "$d"'

Я тестировал его, и он работает с именами файлов, содержащими пробелы, все виды кавычек и т. д. Это важно, потому что если вы запустите, как root, один из этих других скриптов на дереве, файл, созданный:

touch \;\ echo\ hacker::0:0:hacker:\$\'\057\'root:\$\'\057\'bin\$\'\057\'bash

... хорошо угадайте, что ...

13
ответ дан niXar 27 August 2018 в 05:54
поделиться

Никто не предлагает набор символов?

typeset -l new        # always lowercase
find $topPoint |      # not using xargs to make this more readable
  while read old
  do mv "$old" "$new" # quotes for those annoying embedded spaces
  done

В эмуляциях Windows, таких как git bash, это может завершиться неудачно, потому что окна не чувствительны к регистру под капотом. Для этого добавьте шаг, чтобы сначала файл mv на другое имя, например «$ old.tmp», затем на $ new.

0
ответ дан Paul Hodges 27 August 2018 в 05:54
поделиться
( find YOURDIR -type d | sort -r;
  find yourdir -type f ) |
grep -v /CVS | grep -v /SVN |
while read f; do mv -v $f `echo $f | tr '[A-Z]' '[a-z]'`; done

Сначала переименуйте каталоги внизу вверх sort -r (где -depth не доступно), затем файлы. Тогда grep -v / CVS вместо найдет ...- чернослив , потому что он проще. Для больших каталогов для f в ... может переполнять некоторые буферы оболочки. Использовать найти ... | в то время как читать , чтобы избежать этого.

И да, это будет clobber файлы, которые отличаются только в случае ...

0
ответ дан pklausner 27 August 2018 в 05:54
поделиться
  • 1
    Во-первых: find YOURDIR -type d | sort -r - слишком большая проблема. Вы хотите find YOURDIR -depth -type d. Во-вторых, find -type f ДОЛЖЕН запускаться после переименования каталогов. – tzot 30 September 2008 в 12:33

Это работает в CentOS / Redhat или других дистрибутивах без скрипта Perl rename:

for i in $( ls | grep [A-Z] ); do mv -i "$i" "`echo $i | tr 'A-Z' 'a-z'`"; done

Источник: https://linuxconfig.org/rename-all-files-from -uppercase-to-lowercase-characters

(в некоторых дистрибутивах команда по умолчанию rename поступает из util-linux, а это другой, несовместимый инструмент)

70
ответ дан rubo77 27 August 2018 в 05:54
поделиться
  • 1
    & Quot; найти & Quot; следует заменить любой командой, которую вы используете, чтобы получить список файлов, которые вы хотите переименовать; например, "ls *. {C, CPP, H}". – JPaget 6 February 2014 в 21:38
  • 2
    работает в OS X :) – tomasbarrios 10 July 2014 в 21:02
  • 3
    Не работает в OS X, просто печатает информацию об использовании для find. find ., похоже, это исправить. – emlai 25 February 2016 в 20:38
  • 4
    Я добавил цитаты, поэтому он работает с пробелами – rubo77 10 August 2016 в 12:52
  • 5
    Я исправляю его, поэтому он тоже работает с пробелами – rubo77 10 August 2016 в 12:55
  • 6
    Это работает только в одном каталоге, а не рекурсивно – Bram 17 December 2016 в 12:15
  • 7
    "Объединенный" из всех комментариев (ответ больше не редактируется): for f in `find .`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done – romaricdrigon 20 June 2017 в 07:13

Человек, которого вы, ребята, усложняете.

rename 'y / A-Z / a-z /' *

8
ответ дан Stephen 27 August 2018 в 05:54
поделиться
  • 1
    Это не работает, он говорит, что файл с нижним именем уже существует. – kirhgoff 20 February 2017 в 01:47
  • 2
    @kirhgoff Я видел, что это происходит с монтированием NFS - следуйте инструкциям здесь . – joeb 1 June 2017 в 13:43
  • 3
    На мой взгляд, это должен быть выраженный ответ. – Andy 15 November 2017 в 13:50
  • 4
    угадайте, что, несколько по тем же идеям 6 лет назад ... – Xerus 14 July 2018 в 11:12

Это небольшой скрипт оболочки, который делает то, что вы запросили:

root_directory="${1?-please specify parent directory}"
do_it () {
    awk '{ lc= tolower($0); if (lc != $0) print "mv \""  $0 "\" \"" lc "\"" }' | sh
}
# first the folders
find "$root_directory" -depth -type d | do_it
find "$root_directory" ! -type d | do_it

Обратите внимание на действие -depth в первом поиске.

3
ответ дан tzot 27 August 2018 в 05:54
поделиться
  • 1
    Единственное, что работало на Mac из всего потока. Спасибо, кучи! – YemSalat 3 July 2015 в 05:54

Вот мое субоптимальное решение, используя скрипт оболочки bash:

#!/bin/bash
# first, rename all folders
for f in `find . -depth ! -name CVS -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming folder $f"
      mv -f "$f" "$g"
   fi
done

# now, rename all files
for f in `find . ! -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming file $f"
      mv -f "$f" "$g"
   fi
done

Изменить: Я внес некоторые изменения, основанные на предложениях. Теперь все папки переименованы правильно, mv не задает вопросов, когда разрешения не совпадают, а папки CVS не переименовываются (файлы управления CVS внутри этой папки по-прежнему переименованы, к сожалению).

Edit: Since «find -depth» и «find | sort -r» возвращают список папок в удобном для использования порядке для переименования, я предпочитаю использовать «-depth» для поиска папок.

4
ответ дан vividos 27 August 2018 в 05:54
поделиться
  • 1
    Ваша первая находка не работает. Try & quot; mkdir -p A / B / C & quot; а затем запустить скрипт. – tzot 30 September 2008 в 11:55

Если вы используете Arch Linux , вы можете установить пакет rename из AUR , который предоставляет команду renamexm как /usr/bin/renamexm ] и его страницу manual вместе с ней.

Это действительно мощный инструмент для быстрого переименования файлов и каталогов.

Преобразовать в нижний регистр

]
rename -l Developers.mp3 # or --lowcase

Преобразовать в регистр UPPER

rename -u developers.mp3 # or --upcase, long option

Другие опции

-R --recursive # directory and its children

-t --test # dry run, output but don't rename

-o --owner # change file owner as well to user specified

-v --verbose # output what file is renamed and its new name

-s/str/str2 # substite string on pattern

--yes # Confirm all actions

Вы можете выбрать образец Разработчики .mp3 из здесь , если необходимо;)

0
ответ дан w17t 27 August 2018 в 05:54
поделиться
  • 1
    rename from brew на macOS имеет -l, связанный с созданием символической ссылки, а -c - с преобразованием в нижний регистр, поэтому не смотрите. – rien333 12 August 2017 в 18:15
Другие вопросы по тегам:

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