Краткая версия с использованием команды "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"
).
Используя фиксатор файла 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 - это, конечно, скрипт выше)
С 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
Это работает, если у вас уже есть или настроить команду переименования (например, через установку Brew на Mac):
rename --lower-case --force somedir/*
brew install rename
– pduersteler
20 November 2015 в 10:15
rename
не является встроенным bash. Это внешняя утилита, и синтаксис будет отличаться в зависимости от установленной вами версии. Этот ответ недостаточен в качестве переносного решения "для всех ОС на основе UNIX" как заявлено.
– Corey Goldberg
25 November 2017 в 14:18
по-прежнему мне очень нравится
rename 'y/A-Z/a-z/' *
На нечувствительных к регистру файловых системах, таких как HFS + OS X, вам нужно добавить флаг -f
rename -f 'y/A-Z/a-z/' *
The renaming utility that comes by default with Ubuntu is a Perl program sometimes called prename
– sleepsort
8 May 2013 в 16:19
perl-rename
(и предоставляется пакетом с тем же именем)
– jaymmer
13 November 2015 в 05:20
Не переносится, только Zsh, но довольно кратким.
Сначала убедитесь, что загружен zmv
.
autoload -U zmv
Кроме того, убедитесь, что extendedglob
включен:
setopt extendedglob
Затем используйте:
zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'
Для рекурсивно строчных файлов и каталогов, где имя не указано CVS .
Не совсем то, что запросил OP, но то, что я надеялся найти на этой странице:
Версия «slugify» для переименования файлов они похожи на URL-адреса (т. е. включают только буквенно-цифровые, точки и тире):
rename "s/[^a-zA-Z0-9\.]+/-/g" filename
Мне нужно было сделать это на установке 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
Просто попробуйте следовать, если вам не нужно заботиться об эффективности.
zip -r foo.zip foo/*
unzip -LL foo.zip
-0
(это переключатель «zero», без сжатия), zip -0 -r foo.zip foo/
.
– Johnny Baloney
16 February 2016 в 20:29
-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
В этой ситуации я бы выбрал 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])
В 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
for f in `find -depth`; do mv ${f} ${f,,} ; done
find -depth
печатает каждый файл и каталог с содержимым каталога, напечатанным перед самим каталогом. ${f,,}
уменьшает имя файла.
-depth
исправляет это! Это действительно быстрое решение, но, конечно, без использования опции -print0
для поиска, это не самый надежный
– jpaugh
25 February 2016 в 22:08
Ранее опубликованные будут работать совершенно из коробки или с некоторыми настройками для простых случаев, но есть некоторые ситуации, которые вы, возможно, захотите принять во внимание перед запуском пакетного переименования:
ABCdef
, abcDEF
и aBcDeF
? Должен ли переименовать сценарий прерывания или просто предупредить и продолжить? Большинство вышеперечисленных ответов опасны, поскольку они не обрабатывают имена, содержащие нечетные символы. Ваша самая безопасная ставка для такого рода вещей - использовать опцию 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
... хорошо угадайте, что ...
Никто не предлагает набор символов?
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.
( 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 файлы, которые отличаются только в случае ...
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, а это другой, несовместимый инструмент)
find
. find .
, похоже, это исправить.
– emlai
25 February 2016 в 20:38
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 /' *
Это небольшой скрипт оболочки, который делает то, что вы запросили:
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 в первом поиске.
Вот мое субоптимальное решение, используя скрипт оболочки 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» для поиска папок.
Если вы используете Arch Linux , вы можете установить пакет rename
из AUR
, который предоставляет команду renamexm
как /usr/bin/renamexm
] и его страницу manual вместе с ней.
Это действительно мощный инструмент для быстрого переименования файлов и каталогов.
rename -l Developers.mp3 # or --lowcase
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 из здесь , если необходимо;)
blockquote>
brew
на macOS имеет -l
, связанный с созданием символической ссылки, а -c
- с преобразованием в нижний регистр, поэтому не смотрите.
– rien333
12 August 2017 в 18:15
then
-замкнутую строку на(mv "${SRC}" "${DST}.renametmp" && mv "${DST}.renametmp" "${DST}") || echo "${SRC} was not renamed"
. – Lloeki 20 April 2011 в 17:21find my_root_dir -depth -exec rename -c {} \;
. Добавьте -f, чтобы переименовать, если вы находитесь в файловой системе без учета регистра (например, Mac) – Javache 14 August 2011 в 15:24rename
... – Малъ Скрылевъ 9 April 2016 в 09:03