web-dev-qa-db-ja.com

ファイルから特定のコンテンツに対応するコンテンツを選択し、出力ファイルに移動します

Tnsnames.oraというファイルがあり、その内容は以下のとおりです。

NEWDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(Host = linuxerp.de.mph.com)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(Host = linuxerp.de.mph.com)(PORT = 1550))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = newdb)
    )
  )

LISTENER_DG11G =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(Host = linuxerp.de.mph.com)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(Host = linuxerp.de.mph.com)(PORT = 1550))
  )

LISTENER_SABDB =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(Host = linuxerp.de.mph.com)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(Host = linuxerp.de.mph.com)(PORT = 1550))
  )

STEST =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(Host = linuxerp.de.mph.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = STEST)
    )
  )

RBSDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(Host = linuxerp.de.mph.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = RBSDB)
     )
    )

上記のファイルでは、NEWDB =LISTENER_DG11G =LISTENER_SABDB =STEST =RBSDB =はデータベース名であり、それぞれのサービス名はSERVICE_NAME =に含まれています。

したがって、上記のファイルから、データベース名とそれぞれのサービス名を抽出して、Linuxのファイルまたは.xlsに入れようとしています。

出力ファイルは次のようになります

NEWDB   newdb
STEST   STEST
RBSDB   RBSDB

また、サービス名を持たないすべてのデータベースを出力ファイルに追加しないでください。

CSPLITを使用して、最初の行のセットをファイル "X"に移動し、cat X | grep -i "SERVICE_NAME" | cut -d "=" -f2 | rev | cut -d ")" -f2 | rev | awk "NF"を使用して最初の行とSERVICE_NAMEを選択し、それをファイルに移動して、データベースの残りの部分に同じ方法で追加してみました名前。

しかし、それはとても複雑に思えます。それがどのように行われることができるか他のアイデアは高く評価されます。

1

これを処理するより良い方法があると確信していますが、このawkスクリプトのペアでうまくいきます。コメント付きの拡大版または以下のワンライナーのいずれかを使用できます。それらは機能的に同一です。

awk '
    BEGIN { RS="" }                             # Slurp paragraphs
    { print gensub("\n", " ", "g") }            # Replace NL with SPACE
' /tmp/tnsnames.ora |                           # ...in this file

awk '
    /SERVICE_NAME/ {                            # Only process matching lines
        listener=$1;                            # Listener is the first field
        si=NF-2;                                # Count fields back from end of string
        service=gensub(")", "", 1, $si);        # Strip trailing ")"
        printf "%s\t%s\n", listener, service    # Output result
    }
'

サンプル実行

awk 'BEGIN { RS="" } { print gensub("\n", " ", "g") }' /tmp/tnsnames.ora | awk '/SERVICE_NAME/ { listener=$1; si=NF-2; service=gensub(")", "", 1, $si);  printf "%s\t%s\n", listener, service }'
NEWDB   newdb
STEST   STEST
RBSDB   RBSDB
2
roaima
Perl -l -00ne '
my ($blk) = /^\w+/g;

$np = qr/
   \(              # match an opening paren
     (?:
      (?> [^)(]+ ) # one or more non paren, non backtracking
           |
      (??{ $np })  # recurse for more
     )*
   \)              # match a closing paren
/x;

1 while
   /$np
     (?{
        m{ \( CONNECT_DATA \s+ = (?:\s*$np\s*)+ \) }x and
        m{ \( SERVICE_NAME \s+ = \s+ (\w+)      \) }x and
           print join $", $blk, $1 for $&;
     })
   /gx;
' input_file

出力

NEWDB newdb
STEST STEST
RBSDB RBSDB
2
user218374