mv переименование имени файла в _*_

#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