我有一个文件 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”,然后选择第一行和 SERVICE_NAME 使用cat X | grep -i "SERVICE_NAME" | cut -d "=" -f2 | rev | cut -d ")" -f2 | rev | awk "NF"
并将其移动到文件中,并以相同的方式附加到其余数据库名称。
但看起来好复杂啊。任何其他如何完成的想法将不胜感激。
答案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
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