パターンを検索して同じ行に印刷

パターンを検索して同じ行に印刷

次の形式の大きな .txt ファイルがあります。

  Pin name="AR_OP" status="f" 
      Pref x=997.6800 y=2327.0400 side=N width=0.0400 depth=0.3750 /
      Layer id=1 
--
  Pin name="AW_OP" status="f" 
      Pref x=997.6800 y=2327.0400 side=S width=0.0400 depth=0.3750 /
      Layer id=2 

私が望む出力は次のとおりです。

Pin name="AR_OP" side=N
Pin name="AW_OP" side=S

検索したい部分ごとにピン名私が望むピン名と一致します。同じ行に。誰でも助けることができますか?

ベストアンサー1

すべての空白を改行文字に置き換え、Pinまたはで始まるname=行を引き出しますside=。これにより、3つのグループで構成される行が提供されます。 3行で構成される各セットをスペースを区切り文字として使用して、1行に再フォーマットします。

$ tr ' ' '\n' <file | grep -e '^Pin$' -e '^name=' -e '^side=' | paste -d ' ' - - -
Pin name="AR_OP" side=N
Pin name="AW_OP" side=S

これは、すべての値にスペースが含まれていないと仮定します。


文書が次のXML文書で始まったとします。

<?xml version="1.0"?>
<root>
  <Pin name="AR_OP" status="f">
    <Pref x="997.6800" y="2327.0400" side="N" width="0.0400" depth="0.3750"/>
    <Layer id="1"/>
  </Pin>
  <Pin name="AW_OP" status="f">
    <Pref x="997.6800" y="2327.0400" side="S" width="0.0400" depth="0.3750"/>
    <Layer id="2"/>
  </Pin>
</root>

これにより、データは以下からよりよく取得できます。これ後処理バリアントには、テキスト処理ツールの代わりにXML対応ツールを使用してください。

例えば、

xmlstarlet select --template \
    --match  '//Pin' --output 'Pin' \
    --output ' name="' --value-of '@name'      --output '"' \
    --output ' side="' --value-of 'Pref/@side' --output '"' \
    -nl file

これは入力文書内のすべてのノードxmlstarletを見つけるために使用されます。Pin次にそれを繰り返して、そのname属性とPref子ノードの属性を要求された形式で出力します。side

同様の方法そしてxq、よく知られているJSONパーサーの周りのjqXMLパーサーラッパー:

xq -r '.root.Pin | map("Pin name=\"\(."@name")\" side=\"\(.Pref."@side")\"")[]' file

おすすめ記事