grep подстрока, которая является переменной с префиксом точка - PullRequest
0 голосов
/ 12 июня 2018

У меня есть массив, значения которого будут равны namespace=(example examples-ixx) Мне нужно перебрать этот массив, используя цикл for, где я буду хранить example строку в переменной с именем ns.Ниже приведено содержимое файла, который я хотел бы просмотреть.

http://example-service-v2.example-ixx:8080/actuator/info
http://example-service-v2.example:8080/actuator/info

Я пробовал использовать следующие комбинации, однако это не сработало grep -w ".$ns" filename grep -w "\.$ns" filename fgrep -w ".$ns" filename fgrep -w "\.$ns" filename

Я хочу получить точную строку, которая в данный момент назначена переменной $ ns.Не больше не меньше.Может ли кто-нибудь помочь мне с этим.

Ответы [ 3 ]

0 голосов
/ 12 июня 2018

Ваш -w разрушает ваш день.На странице руководства, описывающей опцию -w:

Выберите только те строки, которые содержат совпадения, образующие целые слова.Тест состоит в том, что соответствующая подстрока должна быть либо в начале строки, либо предшествовать не состоящему из слов символу.

Если у вас есть строка v2.example: , символ перед точкой - 2 , который является символом слова и, следовательно, не соответствует.Конечно, вы можете написать

grep -F ".$ns" ....

, но это также поймает .exampleabc .

Пока ваша переменная ns не содержит символов, которые имеют специальное значение в регулярном выражении, вы можете использовать

grep -E "[.]$ns\\>" ....

, поскольку \> соответствует границе слова.Однако, если ns содержит такой символ, это не будет работать.Вы можете улучшить его на

grep -E "[.]\\Q$ns\\E\\>" ....

, потому что то, что находится между \Q и \E, воспринимается буквально, но это решение также не идеально: если ns сам содержит эти специальные escape-символы, вы получите смешнойрезультаты.

Технически, нужно было бы экранировать все символы регулярных выражений внутри ns, но делать это только с помощью инструментов оболочки POSIX - это то, что я даже не заставил бы моего врага сделать это.Если вам действительно нужно решение, которое работает в общем случае, возможно, проще выполнить поиск с помощью небольшого скрипта, написанного на таких языках, как Perl или Ruby, где у вас есть встроенные функции для экранирования регулярных выражений.

0 голосов
/ 13 июня 2018

Мне удалось решить проблему с помощью приведенной ниже команды grep.

grep -P "((?<=^)|(?<=\s))$var(?=(\s|$))"
0 голосов
/ 12 июня 2018

По вашему вопросу, давайте установим массив:

declare -a namespace=(
  example
  example-ixx
)

Затем вы можете пройтись по вашему массиву, запустив grep для каждого элемента.Например:

for ns in "${namespace[@]}"; do
  printf '%s> %s\n' "$ns" "$(grep "\.$ns:" input.txt)"
done

Обратите внимание, что это не защищает от возможности нескольких записей в вашем списке URL-адресов.Конечно, я не знаю, имеет ли это значение.

С другой стороны, вы можете создать регулярное выражение из содержимого вашего массива:

grep -E "\.($(IFS="|$IFS"; printf '%s\n' "${namespace[*]}")):" input.txt

В результате получается один поток вывода, а не обработкаодна строка на элемент массива, и это может быть затруднено включением специальных символов регулярных выражений в исходный массив.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...