簡體   English   中英

使用Sed Awk Bash在搜索中填充變量

[英]Using Sed Awk Bash to populate variable in search

我有幾個包含多個部分的xml文件。 這些文件中的部分之一是“ PublishMgr”。 在本節下面,有兩行包含服務器名稱和端口。 我需要提取服務器和端口,並將它們放入變量並針對它們運行查詢。 我真的不知道有什么簡單的方法可以做到這一點。 我當時在考慮使用awk和sed,但是我對這些知識的了解是有限的。 你能幫忙嗎?
我已經盡力將線條打印出來。 我可以使用awk -F獲取第一個條目的主機名和端口號,但不確定第二行如何做? 如果可能,我希望一次掃描,而不是兩次查詢? 能做到嗎?

請注意,我要將輸出分配給4個不同的變量!

我的密碼

cat filename | grep -A6 PublishMgr | grep "Address\|BacKMeUp"

XML-FILE / TXT僅文件的一部分

<<!--==========================================-->
<!--   PublishMgr                          -->
<!--==========================================-->

<goandpublishme>

<ClassPub name="buylimit" pers="Y">
<prime>host9:1000</prime>
<backup>host145:9999</backup>
</ClassPub>

電流輸出

   <prime>host9:1000</prime>
   <backup>host145:9999</backup>

想要將結果分配給變量的所需輸出請注意,我想將輸出分配給4個“不同”變量。 因此,我可以將它們用於進一步的查詢,就像一個簡單的示例將是cd abc / $ srv1; grep ports $ srv1.log。 簡而言之,我需要有$ srv1 $ srv2 $ port1 $ port2

srv1=host9    
port1=1000    
srv1=host145
port2=9999  

這直接滿足您所需的輸出,並且基於您說您對sed和awk的了解有限的事實。

如果這是您當前的輸出

   <prime>host9:1000</prime>
   <backup>host145:9999</backup>

然后,您可以通過添加帶有多個表達式的sed命令並遍歷行匹配項列表來獲得所需的輸出:

| sed -E -e "s/(^\s*)(<.[^>]*>)/srv$i=/g" -e "s/(<.[^>]*>)//g" -e "s/(:)/\nport$i=/g"

細分如下:

-e "s/(^\\s*)(<.[^>]*>)/srv$i=/g"

  • (^\\s*) -行首,后跟無限制的空格
  • (<.[^>]*>) -這些<>以及中間的任何內容
  • /srv$i=/g替換為srv,后跟增量編號。

-e "s/(<.[^>]*>)//g"刪除前導空格

-e "s/(:)/\\nport=/g"\\n (換行)和port=替換:


接受此測試文件input.txt ,其中包含:

<<!--==========================================-->
<!--   PublishMgr                          -->
<!--==========================================-->

<goandpublishme>

<ClassPub name="buylimit" pers="Y">
<prime>host9:1000</prime>
<backup>host145:9999</backup>
</ClassPub>

您的行列表是: prime backup

遍歷行匹配列表

i=1 ; for predicate in prime backup ; do grep -P "$predicate" <input.txt | sed -E -e "s/(^\s*)(<.[^>]*>)/srv$i=/g" -e "s/(<.[^>]*>)//g" -e "s/(:)/\nport$i=/g" ; (( i++ )) ; done

結果:

srv1=host9
port1=1000
srv2=host145
port2=9999

實際分配(不打印):

OLDIFS="$IFS" ; IFS=$'\n' ; for line in "$(i=1 ; for predicate in prime backup ; do grep -P "$predicate" <input.txt | sed -E -e "s/(^\s*)(<.[^>]*>)/srv$i=/g" -e "s/(<.[^>]*>)//g" -e "s/(:)/\nport$i=/g" ; (( i++ )) ; done)" ; do eval "$line" ; done ; IFS="$OLDIFS"

分解:

#!/bin/bash

OLDIFS="$IFS"                                  #Save current IFS just for good measure
IFS=$'\n'                                      #Set IFS to new-line
for line in "$(i=1
    for predicate in prime backup
        do grep -P "$predicate" <input.txt \
        | sed -E -e "s/(^\s*)(<.[^>]*>)/srv$i=/g"\
             -e "s/(<.[^>]*>)//g" \
             -e "s/(:)/\nport$i=/g"
             (( i++ ))
        done)"                                #The original script broken into lines
        do 
            eval "$line"                      #Actually assign the variables
        done
IFS="$OLDIFS"                                 #Restore IFS

echo "\$srv1 is: $srv1"                       #Print values of assigned variables
echo "\$srv2 is: $srv2"
echo "\$port1 is: $port1"
echo "\$port2 is: $port2"

通常,您不應使用sedawk等面向行的工具來處理XML數據。 您應該改為使用支持XML的工具。 假設您的文檔確實是有效的XML,則可以使用xmlstarlet提取信息:

xmlstarlet sel -t -v 'concat("srv1=", substring-before(//ClassPub/prime, ":"))' -nl \
    -t -v 'concat("port1=", substring-after(//ClassPub/prime, ":"))' -nl publish.xml

只需將prime替換為backup然后相應地調整字符串即可。 我懷疑您可能是說srv2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM