2017-09-06 2 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に "desc"を付けてリストを作成しました:

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

ここで、データfを生成するプログラム私はちょうど間の値をプルする必要があるとして、これは簡単になります考え出し

<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> 
... 

>と<が、私はこれを使用する場合:ILEは次のように見えるようにデータを変更した

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をcontainst任意の行について

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

    、これは変数cは、第3のフィールドに続いて印刷するAWKを伝えます。 3番目のフィールドは、私たちが望む番号です。変数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を使用してa [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' ' ')) 

これは"desc"を含む属性id<setting>タグ値を抽出して行いますdesc\d+"><

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

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

はgrep桁これはdesc\d+"><の間の数字をキャプチャします:配列res

のそれらのアイテムは、第二配列項目の値を確認してください。
注:desc\d+はdesc01に解決だろう、desc02など

-oはグループ
-Pを捕捉するために使用される、それはPerlの正規表現
\Kで伝え
(?=)データのキャプチャを開始するよう指示後読みアサーションは先読みされています一度データのキャプチャを停止するように指示するアサーション<が見つかる

関連する問題