Если я пытаюсь выполнить regex операцию на файлах как так (пример):
$ mv *.ext *.new.ext
Это не работает.
Как я удостоверяюсь, чтобы, когда я обрабатываю в пакетном режиме, переименовали или выполнили операцию на нескольких файлах, что они сохраняют свое текущее имя (не расширение, просто имя)?
Примечание: Я не ищу что-то как rename
управляйте, потому что это должно работать на все, не просто переименовав файлы.
Примечание 2: Хорошо, эти ответы хороши, и объясняет вещи мне, что я правильно не понял прежде.Спасибо!
Рассматриваемую команду, которую я пытаюсь использовать, называют firmtool
, и используется в 3DS доморощенная сцена.
Это упаковывает .bin файлы в .firm файлы, и я хотел бы, чтобы это работало на всех .bin файлах в каталоге, упаковывая их при сохранении настоящего имени.
Вот синтаксис, в котором я нуждаюсь для firmtool
команда:
firmtool build test.firm -n 0x23F00000 -e 0 -D arm9loaderhax.bin -A 0x23F00000 -C NDMA
где test.firm
вывод и arm9loaderhax.bin
вход.
Я хочу выполнить эту команду это, если у меня есть каталог с test1.bin
и test2.bin
то, что это производит test1.firm
и test2.firm
. Сообщите мне, могу ли я использовать регулярное выражение или цикл для завершения этой команды. Спасибо за любую справку!
Хм. Вы can't1, не универсально.
*
подстановочный знак. Оболочка разворачивает его. Когда Вы вводите
*.ext
Оболочка разворачивает его до списка всех файлов соответствия, как:
1.ext 2.ext whatever.ext
Именно это передается команде в Вашем случае mv
. Если mv
получает больше чем два аргумента, последним должен быть каталог, таким образом,
mv *.ext *.new
сбои с *.new
не каталог, потому что mv
получает длинный список аргументов.
Сама оболочка не поддерживает regex, но Linux имеет много утилит, которые делают, как жемчуг переименовывают...
rename -n 's/(.*)\.ext/$1.new/' *
И удалите -n
после тестирования для реального переименования...
Но можно получить переменные имена в переменной и использовать ее для цикличного выполнения по файлам...
for f in *.ext; do echo mv -v -- "$f" "${f/.ext/.new}"; done
и удалите echo
после тестирования для завершения переименования... Можно использовать почти любую команду с for
, не только mv
. Вот немного отличающийся пример на основе Вашего вопроса:
for f in *.bin; do
firmtool build "${f%.bin}.firm" -n 0x23F00000 -e 0 -D "$f" -A 0x23F00000 -C NDMA
done
В этом случае ${f%.bin}
расширится до значения переменной f
с суффиксом .bin
неизолированный (если это имеет такой суффикс; иначе это расширяется до значения f
).
См. руководство по Расширению Параметра Shell для других типов расширения.
1waits, чтобы быть доказанным неправильным
Давайте на самом деле исследуем то, что происходит при использовании капота strace
.
$ touch file{1,2}.ext
$ strace -e trace=execve mv *.ext *.new.ext
execve("/bin/mv", ["mv", "file1.ext", "file2.ext", "*.new.ext"], [/* 80 vars */]) = 0
mv: target '*.new.ext' is not a directory
+++ exited with 1 +++
Поскольку Zanna объяснили в ее ответе *.ext
будет расширен оболочкой до всех файлов в текущем рабочем каталоге тот конец в .ext
строка. То, что Вы видите в том примере, является этим *.new.ext
не расширен, точно потому что нет никакого файла, который соответствует такому шаблону, т.е. нет никакого файла foo.new.ext
где угодно следовательно окружите передачи это непосредственно как аргумент.
mv
управляйте в свою очередь рассматривает это как следующий синтаксис:
mv [OPTION]... SOURCE... DIRECTORY
Если бы у Вас на самом деле был существующий каталог в последнем аргументе, то это работало бы
$ mv *.ext test_dir
$ tree
.
└── test_dir
├── file1.ext
└── file2.ext
Ваша исходная цель, насколько я понимаю, состоит в том, чтобы переименовать каждый *.ext
файл в соответствующий файл с .new.ext
окончание. Это может быть сделано или с, переименовывают, поскольку Zanna показывает, или через цикличное выполнение в оболочке:
$ for f in ./*.ext ; do mv "$f" "$(basename "$f")".new.ext; done
$ ls
file1.ext.new.ext file2.ext.new.ext
Заметьте использование basename
извлечь часть прежде .ext
и использование ./*.ext
. Используйте если ./*
предназначен для предотвращения проблем с именами файлов, которые могут иметь продвижение -
и обычно рекомендуется подход вместо пустого *
В Вашем вопросе Вы заявили:
Если я пытаюсь выполнить regex операцию на файлах
Это - часть проблемы. *
в оболочке Расширение Пути, которое расширяется до списка файлов в текущем рабочем каталоге. Это не работает в том же смысле регулярного выражения abc.*
где Вы строка совпадения, запускающаяся с abc с любым нулем последнего знака или больше раз.
Как я удостоверяюсь, чтобы, когда я обрабатываю в пакетном режиме, переименовали или выполнили операцию на нескольких файлах, что они сохраняют свое текущее имя (не расширение, просто имя)?
Можно выполнить итерации по списку файлов с помощью a for
цикл, и активно извлекает использование имени файла basename
команда, как я показал выше. prename
может использоваться, если Вы правильно определяете замены в regex выражении. О чем хорошо prename
это, это имеет функциональность пробного прогона ( -n
переключатель), где никакое фактическое переименование не выполняется. Та же идея может использоваться с повторением, где Вы используете echo
вместо mv
сначала.
Я не ищу что-то как переименовать команда, потому что это должно работать на все, не просто переименовав файлы.
Снова, *
насколько оболочка затронута соглашения с файлами в текущем каталоге. Это не то же как регулярные выражения. Ваш подход должен быть адаптирован согласно инструментам, которые Вы используете.