См. Подстановочный знак в имени файла

0

Я знаю, что могу использовать подстановочный знак для извлечения файлов с именами определенного формата в bash, используя звездочку, например так:

$ ls
a01     a02     a03     a04     a05     a06     a07     a08     a09     b01     b02     b03     b04     b05     b06     b07     b08     b09
$ ls a*
a01     a02     a03     a04     a05     a06     a07     a08     a09
$ ls b*
b01     b02     b03     b04     b05     b06     b07     b08     b09

Но если бы я хотел сделать что-то вроде перемещения всех файлов, начинающихся с a, в каталог с именем aи перемещения всех файлов, начинающихся с b, в каталог с именем b, как бы я сделал это с помощью одной команды?

Можете ли вы сделать что-то вроде этого:

$ mv *0* */

Но как-то ссылаться на первую звездочку в аргументе перехода?

user3052786
источник

Ответы:

0

Одна команда, одна строка:

for n in *;do [ -f "$n" ] && case "$n" in a*) mv "$n" a/;; b*) mv "$n" b/;; esac; done

Кроме того, вы можете получить имя каталога из имени файла, но я не показывал это изначально, оценивая его как более длинную строку. Например, оператор в цикле будет (первая попытка):

d=$(echo "$n" | sed -e 's/^\(.\).*/\1/'); [ -f "$n" ] && mv "$n" $d/

будет использовать первую букву данного имени файла, чтобы получить имя каталога. Сравнить с

[ -f "$n" ] && case "$n" in a*) mv "$n" a/;; *b) mv "$n" b/;; esac

для рассмотрения дела. На самом деле не намного дольше, но сложнее печатать на лету. Поскольку bashупомянуто, можно использовать его синтаксис подстроки, ${parameter:offset:length}чтобы сократить эту строку:

d=${n:0:1}; [ -f "$n" ] && mv "$n" $d/

или же

[ -f "$n" ] && mv "$n" ${n:0:1}/

(Я вспоминаю это как расширение bash и не нахожу его в POSIX ).

Что касается фактического вопроса о повторном использовании подстановочных знаков: это, очевидно, относится к расширению скобок . Они расширяются до того момента, когда они вам понадобятся. Цитирование документации:

Раскладка скобок выполняется перед любыми другими расширениями, и любые символы, специально предназначенные для других расширений, сохраняются в результате. Это строго текстуально . Bash не применяет синтаксическую интерпретацию к контексту расширения или к тексту между фигурными скобками. Чтобы избежать конфликтов с расширением параметра, строка '$ {' не считается допустимой для расширения скобки.

Томас Дики
источник
Вау, это намного более запутанно, чем я ожидал. Значит, в регулярных выражениях нет ничего похожего на обратные ссылки?
user3052786
да / нет: не с подстановочными знаками, а только для расширенных имен. Цикл, который я показывал, жестко кодирует имена и выглядит длинным - но перевод имени добавил бы около трети к длине строки, поэтому я остановился на этом. В примере проверяется, что источником является файл, что делает его немного длиннее.
Томас Дики
В bash есть замены, которых следует избегать sed- я делаю большую часть сценариев для приложений POSIX.
Томас Дики