выведите путь к директории после сопоставления ее имени с подстановочными знаками

#awk #path #wildcard

Вопрос:

Я застрял с этой маленькой головоломкой. Заранее благодарю вас за помощь.

У меня есть путь к каталогу, и я хотел бы напечатать его путь после совпадения.

Нравится

 echo /Users/user/Documents/terraform-shared-infra/services/history_book_test | awk -F "terraform-|tfRepo-" '{print $(NF)}'

echo /Users/user/Documents/tfRepo-shared-infra/services/history_book_test | awk -F "terraform-|tfRepo-" '{print $(NF)}'
 

выход:

 shared-infra/services/history_book_test

shared-infra/services/history_book_test
 

Когда я пытаюсь добавить подстановочный знак в terraform-* это не работает.

Я хотел бы напечатать путь после совпадения с terraform-* или tfRepo*. Нравится:

 services/history_book_test
services/history_book_test/../.. so on.
 

с sed:

 echo /Users/user/Documents/terraform-shared-infra/services/history_book_test | sed 's|.*terraform.([^/]*)/.*|1|'
shared-infra
 

Пробовал разные способы с awk и grep, но безуспешно. Любые зацепки или идеи, которые я могу попробовать. Пожалуйста.

Спасибо.

Ответ №1:

Вы путаете регулярные выражения с глобальными шаблонами. Оба имеют подстановочные знаки и выглядят одинаково, но имеют совершенно разные значения и применения. регулярные выражения используются такими инструментами обработки текста, как grep, sed и awk, для сопоставления текста во входных строках, в то время как шаблоны глобирования используются оболочками для сопоставления имен файлов/каталогов. Например, foo* в регулярном выражении означает fo , что за ним следует ноль или более дополнительных o s, foo* в то время как в шаблоне глобулирования означает foo , что за ним следует ноль или более других символов (что в регулярном выражении было бы foo.* ). Поэтому никогда не говорите просто «подстановочный знак», для ясности скажите «подстановочный знак регулярного выражения» или «подстановочный знак глобуса».

Это может быть то, что вы пытаетесь сделать, используя sed, в котором есть -E аргумент для включения EREs, например GNU или BSD sed:

 $ sed -E 's:.*/(terraform|tfRepo)-[^/]*/::' file
services/history_book_test
services/history_book_test
 

или с помощью любого awk:

 $ awk '{sub(".*/(terraform|tfRepo)-[^/]*/","")} 1' file
services/history_book_test
services/history_book_test
 

Что касается вашей попытки с sed sed 's|.*terraform.([^/]*)/.*|1|' — если вы собираетесь использовать символ, отличный от / разделителей, не используйте символ, как будто | это метасимвол регулярного выражения или обратной ссылки, в лучшем случае, который запутывает ваш код, вместо этого выберите какой-нибудь символ, который всегда является буквальным, например : .

Комментарии:

1. большое вам спасибо, @Эдмортон, сэр. Также для ясного объяснения.