首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用awk解析TNSNAMES.ORA的最佳方法

使用awk解析TNSNAMES.ORA的最佳方法
EN

Stack Overflow用户
提问于 2018-08-23 17:23:14
回答 1查看 751关注 0票数 1

我构建了一个函数来解析Tnsnames.ora文件。我的问题是有一个更好的awk语句/查询将给我我想要的结果。

这是我想要改进的语句,因此我将有一个更短的代码段:

awk "BEGIN{found=0}/${entry}/{found=1} {if (查找) print }")

我想摆脱for循环,使用AWK搜索和查找单个TNSNAME。目前,我正在通过awk命令的结果进行计数,直到我到达传递的名称的最后一个。

代码语言:javascript
复制
findTnsname()
{
#!/bin/ksh
#inputs:
# $1: stanza title
# $2: Fully qualified input filename
#$3 set to yes will echo how many were found
tnsnames=$(cat $2)
entries=$(echo "$tnsnames"| grep -i "$1.*="| awk '{print $1}')
eNames=$(echo "$entries" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/,/g')
ecount=$(echo "$entries" | wc -l | awk '{print $1}')
if [ "$3" = "yes" ] ; then
  echo "# found ${ecount} entries -  ${eNames} "
fi
for entry in $entries
{
  #echo "#searching for ${entry}"
  tt=$(echo "$tnsnames" | awk "BEGIN{found=0}/${entry}/{found=1} {if (found) print }")
  t=0     # t for target, means the stanza has been found
  open_parens=0
  close_parens=0
  if [[ -n $tt ]] ; then
    echo "$tt" | while read -r i; do
            if(( t == 1 )); then
                    echo "$i"
                    newline_ck=$(echo "$i" | egrep "^$" | wc -l | awk '{print $1}') 
                    if(( newline_ck > 0 )); then
                            t=0
                            break
                    elif(( open_parens == close_parens && open_parens != 0 )); then
                            t=0

                    else
                            (( open_parens += $(echo "$i" | awk -F"(" '{print NF-1}') ))
                            (( close_parens += $(echo "$i" | awk -F")" '{print NF-1}') ))
                            #echo "# open ${open_parens} close ${close_parens} t ${t}"
                    fi
            else
                    t=$(echo "$i" | egrep -i "^$entry" | wc | awk '{print $1}')
                    if(( t == 1 )); then
                            echo "$i"
                    fi
            fi
    done 
   else
     echo "$entry does not exist in $2"
   fi
 } 
}

结果如下:"$ORACLE_HOME/network/admin/tnsnames.ora" findTnsname

代码语言:javascript
复制
ABC_USR.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hosta.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ABC_usr)
)
)

ABCT.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hostb.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ABCt)
)
)

样本输入

代码语言:javascript
复制
DEF_USR.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hosta.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DEF_USR)
)
)

DEFT.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hostb.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DEFT)
)
)

DEF_USR.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hostc.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DEF_USR)
)
)

DEFT.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hostd.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DEFT)
)
)
GHI_USR.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hoste.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = GHI_USR)
)
)

GHIT.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hostf.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = GHIT)
)
)
ABC_USR.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hosta.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ABC_usr)
)
)

ABCT.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hostb.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ABCt)
)
)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-23 20:56:27

这可能是你想要的,这取决于我在你问题下面的评论中提出的问题的答案:

如果您的输入记录总是像您在一个注释中建议的那样在它们之间有空行,那么您所需要的就是:

代码语言:javascript
复制
$ awk -v key='abc' -v RS= -v ORS='\n\n' 'tolower($0)~tolower(key)' file

否则,如果它们有时不像所提供的样例输入那样:

代码语言:javascript
复制
$ cat tst.awk
!NF { next }
!/[()]/ { prt(); rec="" }
{ rec = rec $0 ORS }
END { prt() }
function prt() {
    if ( tolower(rec) ~ tolower(key) ) {
        print rec
    }
}

$ awk -v key='abc' -f tst.awk file
ABC_USR.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hosta.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ABC_usr)
)
)

ABCT.some.company.com =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = hostb.some.company.com)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ABCt)
)
)

编辑-为了更好地控制在哪里搜索哪些字段和打印什么,还需要考虑其他问题:

代码语言:javascript
复制
$ cat tst.awk
BEGIN { FS=RS; RS=""; ORS="\n" }
{
    delete f

    f["NAME"] = $1
    sub(/[[:space:]]*=.*/,"",f["NAME"])

    for (i=2; i<=NF; i++) {
        n = split($i,tmp,/[ =()]+/)
        for (j=n-2; j>1; j-=2) {
            f[tmp[j]] = tmp[j+1]
        }
    }

    prt()
}

function prt() {
    for (tag in f) {
        print tag "=<" f[tag] ">"
    }
    print "----"
}

代码语言:javascript
复制
$ awk -f tst.awk file
LOAD_BALANCE=<yes>
HOST=<hosta.some.company.com>
PROTOCOL=<TCP>
NAME=<DEF_USR.some.company.com>
SERVICE_NAME=<DEF_USR>
SERVER=<DEDICATED>
PORT=<1521>
----
LOAD_BALANCE=<yes>
HOST=<hostb.some.company.com>
PROTOCOL=<TCP>
NAME=<DEFT.some.company.com>
SERVICE_NAME=<DEFT>
SERVER=<DEDICATED>
PORT=<1521>
----
LOAD_BALANCE=<yes>
HOST=<hostc.some.company.com>
PROTOCOL=<TCP>
NAME=<DEF_USR.some.company.com>
SERVICE_NAME=<DEF_USR>
SERVER=<DEDICATED>
PORT=<1521>
----
LOAD_BALANCE=<yes>
HOST=<hostd.some.company.com>
PROTOCOL=<TCP>
NAME=<DEFT.some.company.com>
SERVICE_NAME=<DEFT>
SERVER=<DEDICATED>
PORT=<1521>
----
LOAD_BALANCE=<yes>
HOST=<hoste.some.company.com>
PROTOCOL=<TCP>
NAME=<GHI_USR.some.company.com>
SERVICE_NAME=<GHI_USR>
SERVER=<DEDICATED>
PORT=<1521>
----
LOAD_BALANCE=<yes>
HOST=<hostf.some.company.com>
PROTOCOL=<TCP>
NAME=<GHIT.some.company.com>
SERVICE_NAME=<GHIT>
SERVER=<DEDICATED>
PORT=<1521>
----
LOAD_BALANCE=<yes>
HOST=<hosta.some.company.com>
PROTOCOL=<TCP>
NAME=<ABC_USR.some.company.com>
SERVICE_NAME=<ABC_usr>
SERVER=<DEDICATED>
PORT=<1521>
----
LOAD_BALANCE=<yes>
HOST=<hostb.some.company.com>
PROTOCOL=<TCP>
NAME=<ABCT.some.company.com>
SERVICE_NAME=<ABCt>
SERVER=<DEDICATED>
PORT=<1521>
----
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51991210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档