#linux #bash #unix
#linux #bash #unix
Вопрос:
Приведен пример, что мое имя файла — A_BC_DEF_GH_IJ_LMNO_PQ_11111111_11111111_111111_111111_AB.dat.meta
я пытаюсь переименовать это с помощью команды unix, но когда я попытался использовать этот cmd
for f in *.meta; do mv "$f" "$(echo $f|sed s/[0-9]/?/g|sed 's/-/*/g')" ; done
мой файл переименован в
A_BC_DEF_GH_IJ_LMNO_PQ_????????_????????????????????_???????_AB.dat.meta
ожидается, что файл будет переименован в
A_BC_DEF_GH_IJ_LMNO_PQ__????????_????????????????????_*_AB.dat.meta
Я совсем новичок в unix cmd, какой-нибудь подход, который я должен попробовать?
Комментарии:
1. Не рекомендуется включать
*
s в имена файлов, хотя это технически возможно. Есть ли какая-либо конкретная причина для этого?2. Потому что в папке мне нужно будет переименовать все файлы с расширением .meta . поэтому вместо того, чтобы переименовывать отдельных, я сделаю это только с помощью одной функции
3. Я понимаю, что вам нужно переименование. Мне любопытно, почему вам нужно включить
*
в имена файлов. Это может конфликтовать сfile globbing
, и вам нужно обратить внимание и приложить дополнительные усилия, чтобы правильно обработать их после переименования. (Символ?
также подвержен аналогичному риску.)4. Почему
_
он был заменен__
и как????????
увеличился средний счет?
Ответ №1:
Поскольку [0-9]
и ?
подвергаются расширению имени файла, вы должны указать их, чтобы избежать неприятных сообщений об ошибках. Имея это в виду, я сделал
echo A_BC_DEF_GH_IJ_LMNO_PQ_11111111_1111111111_111111_AB.dat.meta | sed 's/[0-9]/?/g'|sed 's/-/*/g'
и получил в качестве вывода A_BC_DEF_GH_IJ_LMNO_PQ???????????????????????? AB.dat.meta, что имеет для меня смысл. Почему вы ожидаете появления звездочки в результирующем имени файла? В вашей второй команде sed вы превращаете дефисы в звездочки, но во входных данных дефис отсутствует.
Конечно, довольно бессмысленно использовать вопросительные знаки и звездочки в имени файла, поскольку это просто напрашивается на неприятности, но нет закона, запрещающего это делать.
Ответ №2:
A_BC_DEF_GH_IJ_LMNO_PQ_11111111_11111111_111111_111111_AB.dat.meta
Сопоставьте его с регулярным выражением. Помните, какие символы нужно экранировать в sed. Помните о правильном цитировании — если вы пишете $
, оно должно быть внутри "
. Обратите внимание, что если имен файлов нет *.meta
, он будет просто перебирать строку *.meta
, если nullglob
не задано.
$ touch A_BC_DEF_GH_IJ_LMNO_PQ_11111111_1111111111_111111_AB.dat.meta
$ for f in *.meta; do mv "$f" "$(echo "$f" | sed 's/[0-9]/?/g; s/_(?*)_(?*)_(?*)_([^_]*)$/__1_2_*_4/')" ; done