Как Bash может переименовать серию пакетов, чтобы удалить их номера версий? Я играл с обоими expr
и%%
безрезультатно.
Примеры:
Xft2-2.1.13.pkg
становится Xft2.pkg
jasper-1.900.1.pkg
становится jasper.pkg
xorg-libXrandr-1.2.3.pkg
становится xorg-libXrandr.pkg
bash
shell
file-rename
Джереми Л
источник
источник
Ответы:
Вы можете использовать функцию расширения параметров bash
Кавычки необходимы для имен файлов с пробелами.
источник
rename "s/-[0-9.]*//" *.pkg
Если все файлы находятся в одном каталоге, последовательность
сделаю вашу работу. Команда sed создаст последовательность команд mv , которые затем можно передать оболочке. Лучше всего сначала запустить конвейер без конечной точки,
| sh
чтобы убедиться, что команда выполняет то, что вы хотите.Для рекурсии через несколько каталогов используйте что-то вроде
Обратите внимание, что в sed последовательность группировки регулярных выражений представляет собой скобки, которым предшествует обратная косая черта,
\(
и\)
, а не одиночные скобки(
и)
.источник
ls
в скриптах. Первое разнообразие может быть достигнуто сprintf '%s\n' * | sed ...
помощью некоторого творчества, и вы, вероятно, также сможете избавиться от негоsed
. Bashprintf
предлагает'%q'
код формата, который может пригодиться, если у вас есть имена файлов, содержащие буквальные метасимволы оболочки.Сделаю примерно так:
Предполагается, что все ваши файлы находятся в текущем каталоге. Если нет, попробуйте использовать find, как посоветовал выше Хавьер.
РЕДАКТИРОВАТЬ : Кроме того, в этой версии не используются какие-либо специфические для bash функции, как в других выше, что приводит к большей переносимости.
источник
Вот POSIX, почти эквивалент принятого в настоящее время ответа . Это заменяет
${variable/substring/replacement}
расширение параметров Bash на расширение, доступное в любой Bourne-совместимой оболочке.Расширение параметра
${variable%pattern}
дает значениеvariable
сpattern
удаленным суффиксом . (Также есть${variable#pattern}
возможность удалить приставку.)Я сохранил подшаблон
-[0-9.]*
из принятого ответа, хотя, возможно, он вводит в заблуждение. Это не регулярное выражение, а шаблон глобуса; поэтому это не означает «тире, за которым следует ноль или более цифр или точек». Вместо этого оно означает «тире, за которым следует число или точка, за которыми следует что угодно». «Все» будет самым коротким, а не самым длинным совпадением. (Bash предлагает##
и%%
для обрезки самого длинного префикса или суффикса, а не самого короткого.)источник
Мы можем предположить, что
sed
он доступен на любом * nix, но мы не можем быть уверены, что он поддерживаетsed -n
генерацию команд mv. ( ПРИМЕЧАНИЕ:sed
это делает только GNU .)Даже в этом случае с помощью встроенных команд bash и sed мы можем быстро создать для этого функцию оболочки.
использование
Создание целевых папок:
Поскольку
mv
не создает целевые папки автоматически, мы не можем использовать нашу первоначальную версиюsedrename
.Это довольно небольшое изменение, поэтому было бы неплохо добавить эту функцию:
Нам понадобится служебная функция
abspath
(или абсолютный путь), поскольку в bash нет этой сборки.Получив это, мы можем создать целевую папку (и) для шаблона sed / rename, который включает новую структуру папок.
Это гарантирует, что мы знаем имена наших целевых папок. Когда мы переименовываем, нам нужно будет использовать его в имени целевого файла.
Вот полный скрипт с поддержкой папок ...
Конечно, это все еще работает, когда у нас нет определенных целевых папок.
Если мы хотим поместить все песни в папку,
./Beethoven/
мы можем сделать это:использование
Бонусный раунд ...
Используя этот скрипт для перемещения файлов из папок в одну папку:
Предполагая, что мы хотим собрать все совпавшие файлы и поместить их в текущую папку, мы можем это сделать:
Примечание о шаблонах регулярных выражений sed
В этом скрипте применяются обычные правила шаблона sed, эти шаблоны не являются PCRE (Perl-совместимые регулярные выражения). Вы можете использовать расширенный синтаксис регулярных выражений sed, используя любой из них
sed -r
или вsed -E
зависимости от вашей платформы.См. POSIX-совместимый
man re_format
для полного описания базовых и расширенных шаблонов регулярных выражений sed.источник
Я считаю, что переименование - гораздо более простой инструмент для такого рода вещей. Я нашел это на Homebrew для OSX
Для вашего примера я бы сделал:
'S' означает замену. Форма - s / searchPattern / replace / files_to_apply. Для этого вам нужно использовать регулярное выражение, что требует небольшого изучения, но оно того стоит.
источник
for
иsed
т. Д., Но гораздо проще и быстрее использовать,rename
если вы часто делаете это.rename
команда; кроме того, у некоторых будут разныеrename
команды с разными функциями, синтаксисом и / или параметрами. Это похоже наrename
довольно популярный Perl ; но ответ должен прояснить это.лучше использовать
sed
для этого что-то вроде:выяснение регулярного выражения оставлено как упражнение (как и работа с именами файлов, которые включают пробелы)
источник
Кажется, это работает при условии, что
удалите .pkg, затем удалите - ..
источник
-e
. Напрsed -e 's/\.pkg//g' -e 's/-.*//g'
.ls
вывод и не заключайте переменные в кавычки. См. Также shellcheck.net для диагностики распространенных проблем и антипаттернов в сценариях оболочки.Мне нужно
*.txt
было переименовать несколько файлов, как.sql
в одной папке. ниже работал у меня:источник
Спасибо за ответы. У меня тоже была какая-то проблема. Перемещение файлов .nzb из очереди в файлы .nzb. В именах файлов были пробелы и другой мусор, и это решило мою проблему:
Он основан на ответе Диомидиса Спинеллиса.
Регулярное выражение создает одну группу для всего имени файла и одну группу для части до .nzb.queued, а затем создает команду перемещения оболочки. С цитируемыми строками. Это также позволяет избежать создания цикла в сценарии оболочки, потому что это уже сделано sed.
источник
-n
опцию таким же образом.