2017-09-06 49 views
1

我有一個grep行,其他人爲我提供,我不知道如何改變。多行grep不製作列表

原始線是這樣的:

grep id=\"desc\"* $ADDON_SETTINGS | awk -v ORS=, '{gsub(/"/, "");print $2}' | tr -s 'value=' ' ' | sed 's/ //g' | echo "[$(cat)]" 

它從包含一個文件的以下(這是一個樣本段)被拉:

<settings> 
    <setting id="cfirst" value="false" /> 
    <setting id="cicons" value="false" /> 
    <setting id="days" value="3" /> 
    <setting id="delay" value="0.000000" /> 
    <setting id="desc01" value="10" /> 
    <setting id="desc02" value="18" /> 
    <setting id="desc03" value="6" /> 
    <setting id="desc04" value="13" /> 
    <setting id="desc05" value="6" /> 
... 

它拉出值用於與線在ID「遞減」,併產生了一個清單:

10,18,6,13,6... 

現在,生成數據F程序ILE已更改的數據看起來像這樣:

<settings version="2"> 
    <setting id="allc" default="true">false</setting> 
    <setting id="cfirst" default="true">false</setting> 
    <setting id="cicons" default="true">false</setting> 
    <setting id="days">3</setting> 
    <setting id="delay" default="true">0</setting> 
    <setting id="desc01">10</setting> 
    <setting id="desc02">18</setting> 
    <setting id="desc03">6</setting> 
    <setting id="desc04">13</setting> 
... 

我想我只需要拉之間>和<但值,這可能是更容易,如果我用這個:

grep id=\"desc\"* $ADDON_SETTINGS | awk -v ORS=, '{">|<";print $3}' | echo "[$(cat)]" 

但它的不正確。不知道我錯過了什麼。

回答

0

嘗試:

$ awk -F'[<>]' '/"desc/{printf "%s%s",c,$3; c=","} END{print""}' file 
10,18,6,13 

工作原理:

  • -F'[<>]'

    這告訴AWK使用<>作爲字段分隔。

  • /"desc/{printf "%s%s",c,$3; c=","}

    對於containst "desc任何線,這會告訴awk打印可變c接着第三個字段。第三個領域是我們想要的數字。變量c最初是空字符串,但在第一次打印後,我們將其設置爲逗號,。這會導致我們想要打印的數字,每個數字都以逗號分隔。

  • END{print""}

    後,我們已經讀完了文件,這會告訴awk將打印一個換行符。

0

您的解決方案不起作用的原因是'{">|<";print $3}',這是沒有意義的。表達式">|<"不做任何事情。你想這樣一行:

$ grep id=\"desc input.txt | awk -F"<|>" '{print $3}' 

然而,單一AWK的解決方案是:

awk 'match($0,/id=\"desc[0-9]+\">([0-9]+)/, a){printf "%s%s",sep,a[1];sep=","} END{print ""}' input.txt 
10,18,6,13 

或:與文件:

$ cat tst.awk 
match($0,/id=\"desc[0-9]+\">([0-9]+)/, a){ 
    printf "%s%s",sep,a[1];sep="," 
} 
END{print ""} 

$ awk -f tst.awk input.txt 
10,18,6,13 

說明:

  • 與正則表達式匹配id=\"desc[0-9]+\">([0-9]+)將括號中的數字放在[1]中。
  • 用分隔符sep打印一個[1],它第一次沒有值。
  • END:您需要打印換行符。
0

您的內容有html/xml格式。
正確的方法是使用html/xml解析器。

xmlstarlet解決方案:

樣品input.html內容:

<settings version="2"> 
    <setting id="allc" default="true">false</setting> 
    <setting id="cfirst" default="true">false</setting> 
    <setting id="cicons" default="true">false</setting> 
    <setting id="days">3</setting> 
    <setting id="delay" default="true">0</setting> 
    <setting id="desc01">10</setting> 
    <setting id="desc02">18</setting> 
    <setting id="desc03">6</setting> 
    <setting id="desc04">13</setting> 
</settings> 

的工作:

res=($(xmlstarlet sel -t -v "//setting[contains(@id, 'desc')]" 1.html | tr '\n' ' ')) 

這將提取<setting>標籤值包含"desc"屬性id,使這些項目的陣列res

檢查第2個數組項值:

echo ${res[1]} 
18 
+0

這可能是最好的方式去作爲文件是XML。我使用'xmlstarlet sel -t -v「/ settings/setting [contains(@id,'cicons')]」$ ADDON_SETTINGS'來計算常規設置,但我需要輸出所有'「desc」用逗號隔開的行。因此,上面代碼段的輸出應該是'10,18,6,13' – edit4ever

+0

@ edit4ever,只需將'tr'\ n''''改爲'tr'\ n'','期望的序列 – RomanPerekhrest

0

的grepdesc\d+"><

grep -oP 'desc\d+">\K\d+(?=<)' file | paste -sd "," 

之間的數字這將捕獲desc\d+"><之間的數字。
注:desc\d+將解析desc01,desc02等

-o用於捕獲組
-P告訴它是一個Perl的正則表達式
\K是向後斷言它告訴開始捕獲數據
(?=)是一個超前斷言這裏告訴停止捕獲數據一次<被發現