Или вы можете использовать чистый bash ... (кроме mv, то есть ..)
for file in *.htm; do mv "$file" "$.html"; done
и избегать неприятных базовых вещей. ;)
Bash имеет обширный набор параметров расширения переменных. Используемый здесь «%» удаляет наименьший соответствующий суффикс из значения переменной. Шаблон является шаблоном глобуса, поэтому $также будет работать. Оператор '%%' удаляет самый большой соответствующий суффикс и является взаимозаменяемым в приведенном выше примере, так как шаблон является фиксированным, $.htmlхотя превратит abhtm в a.html.
Посмотрите раздел подстановки переменных на man-странице bash для более изящных приемов. В bash можно многое сделать напрямую.
Также обратите внимание, что эти расширения параметров не ограничиваются * bash *. Они доступны для всех оболочек, производных от Борна (* sh *, * ksh *, * bash *, * zsh *, * dash *, * ash * и т. Д.). Расширения являются частью [спецификации POSIX для «Командного языка оболочки»] (http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02) и легко переносимы.
Chris Johnsen 14 лет назад
1
11
TRS-80
rename(1)утилита Perl, которая делает именно то, что вы хотите В этом случае:
rename 's/\.htm$/.html/' *htm
или если вы используете подкаталоги, а также
(требуется Bash 4.0 и настройки globstar: shopt -s globstar)
rename 's/\.htm$/.html/' **/*htm
переименовать проще, но это не стандартная программа unix; Оригинальный вопрос не указывает, какой Unix. Кажется, в некоторых местах "prename".
freiheit 15 лет назад
1
`Rename` поставляется с Perl, и в основном каждый Unix поставляется с Perl в наши дни.
TRS-80 15 лет назад
2
да, но не каждый Unix включает вспомогательные программы, такие как «переименование», когда они помещают Perl в систему. OSX, например, не имеет "переименовать" на нем.
freiheit 15 лет назад
3
@William: Синтаксис двойной звездочки доступен только в Bash 4 и выше и только если он включен с помощью `shopt -s globstar` (по умолчанию выключен). Кроме того, в Linux и Unix есть каталоги, а не папки.
Dennis Williamson 12 лет назад
1
11
Dennis Williamson
В именах файлов не должно быть пробелов, символов новой строки или других пробелов, но эта версия ответа freiheit обрабатывает их. Он также использует $()вместо обратных галочек для удобочитаемости наряду с другими преимуществами.
for file in *.htm do mv "$file" "$(basename "$file" .htm).html" done
Еще лучше - для особого случая просто добавить в конец:
for file in *.htm do mv "$file" "$l" done
6
freiheit
for file in *.htm; do mv $file `basename "$file" .htm`.html done
Попробуйте это echoперед mvпервым разом.
Проблема с вашим оригиналом в том, что " mv *.htm *.html" *обрабатывает s с помощью оболочки, поэтому mvкоманда просто видит список всех файлов .htm и .html в текущем каталоге. Другими словами, что-то вроде " mv foo.htm bar.htm stuff.htm six.htm file.htm". mv знает, как обрабатывать более двух аргументов, если последний является каталогом.
Вы должны указать "$ file", чтобы обрабатывать пробелы.
Richard Hoskins 15 лет назад
1
Ваше описание исходной проблемы должно быть подчеркнуто сильнее. Такое поведение с подстановочными знаками оболочки удивительно и не интуитивно понятно для кого-то из Windows, и понимание того, что делает оболочка, дает понять, почему оригинальное приложение `mv` не будет работать.
Greg Hewgill 15 лет назад
0
3
xalupadas
Еще один пример чистого bash с использованием string replace.
for file in *.htm; do mv $file $; done
Extra - это заменяет все вхождения строки
for file in *.htm; do mv $file $; done
1
Martin
Если вы используете Zsh, вы можете использовать 'ZMV'
Ваш пример использования не удался. Вам нужно сбежать `#`.
Cristian Ciupitu 15 лет назад
1
Нет, это работает (я ВСЕГДА проверяю перед публикацией в SuperUser). Необходимость экранирования # зависит от используемой вами оболочки (я использую zsh).
bortzmeyer 15 лет назад
0
0
Cristian Ciupitu
Пакет util-linux-ng (в Fedora) имеет renameкоманду, аналогичную команде, упомянутой в TRS-80 . Вы можете использовать это так: