rename(1) набор файлов за пределами текущего каталога
rename
Команда в Ubuntu 12.04 (manpage говорит, что она является частью perl v5.14.2 2012-03-23) хорошо работает в одном каталоге, но я хочу использовать ее и в подкаталогах (или, в более общем случае, в списке файлов, который является вывод другой команды через обратные кавычки). Например, я бы ожидал
rename "s/ /-/g" `find .`
изменить все пробелы на тире во всех именах файлов ниже текущего каталога. Но эта команда ничего не делает.
(Изменить: изменено rename -n
в rename
, Этот вариант хорош для безопасного эксперимента, но только отвлекает.)
Обратные кавычки не виноваты, потому что замена find .
например echo */*
работает.
Сначала делать find . > foo
, а затем заменить find .
с cat foo
, ничего не делает.
Даже свернуть список файлов в одну строку, заменив find .
с find . | tr -d '\n'
, ничего не делает.
Какой элемент виноват?
1 ответ
Это не будет работать:
rename 's/ /-/g' `find .`
После запуска команды find оболочка выполняет разбиение слов по результатам. Следовательно, ни одно имя файла с пробелами не сохраняется в такте: оно разбивается на части.
Вы можете избежать этого, используя:
rename 's/ /-/g' */*
В этой форме команды оболочка не выполняет разбиение слов, и ваш rename
преуспеет. Эта форма работает даже для имен файлов с пробелами, вкладками или любыми другими сложными символами.
Или используйте find -exec
:
find . -name '* *' -exec rename 's/ /-/g' {} +
Эта форма будет работать с именами файлов, имеющими пробелы, символы табуляции или любые другие сложные символы.
демонстрация
Чтобы увидеть, что идет не так, давайте создадим файл с пробелами
$ touch "a b c"
$ find .
.
./a b c
Чтобы прояснить, что происходит, давайте создадим функцию, которая помещает каждый аргумент, который он видит, в двойные кавычки и отображает его:
$ display() { printf '"%s"\n' "$@"; }
Теперь мы можем использовать display
чтобы увидеть, что происходит, когда мы бежим find .
:
$ display `find .`
"."
"./a"
"b"
"c"
Это показывает разделение слов в действии. Имя файла a b c
был разделен на три отдельных слова.