Выполните действие на линейном диапазоне в sed / awk - PullRequest
2 голосов
/ 02 июня 2009

Как мне извлечь определенные переменные из определенного диапазона строк в sed / awk?

Пример: я хочу извлечь хост и порт из .tnsnames.ora из этого раздела, который начинается в строке 105.

DB_CONNECTION=
   (description=
     (address=
         (protocol=tcp)
         (host=127.0.0.1)
         (port=1234)
      )
      (connect_data=
         (sid=ABCD)
         (sdu=4321)
  )

Ответы [ 4 ]

2 голосов
/ 02 июня 2009

gawk может использовать регулярное выражение в разделителе полей (FS).

'$ 0 = $ 2' всегда верно, поэтому автоматически этот скрипт выводит $ 2.

$ gawk -F'[()]' 'NR>105&&NR<115&&(/host/||/port/)&&$0=$2' .tnsnames.ora
1 голос
/ 02 июня 2009

@ lk, чтобы ответить на ответ, который вы разместили:

Вы можете написать код awk, например, C, но он более кратко выражен в виде пар "pattern {action}".

Если у вас есть gawk или nawk , разделитель поля будет ERE , как сказал Хирофуми Сайто

gawk -F'[()=]' '
    NR < 105 {next}
    NR > 115 {exit}
    $2 == "host" || $2 == "port" {
        # do stuff with $2 and $3
        print $2 "=" $3
    } 
'
1 голос
/ 02 июня 2009

Вы можете использовать диапазоны адресов, чтобы указать, к какому разделу применять регулярные выражения. Если вы оставите адрес конца строки вне поля (оставьте запятую), он будет соответствовать концу файла. Вы также можете «связать» несколько выражений, используя «-e» несколько раз. Следующее выражение просто выведет порт и значение хоста в стандартный вывод. Он использует обратные ссылки (\ 1) для того, чтобы просто напечатать соответствующие детали.

sed -n -e '105,115s/(port=\([0-9].*\))/\1/p' -e '105,115s/(host=\([0-9\.].*\))/\1/p' tnsnames.ora 
1 голос
/ 02 июня 2009

использование:

sed '105, $ <любой код sed, который вы хотите здесь>'

Если вы хотите указать хост и порт, вы можете сделать что-то вроде:

sed .tnsnames.ora  '105,115p'|grep -e 'host=' -e 'port='
...