awkを使用して行を一致させ、マージし、Solarisを使用して印刷する

awkを使用して行を一致させ、マージし、Solarisを使用して印刷する

パターンを合わせたいです。アッSolaris システムの場合。

$ luxadm probe 
 No Network Array enclosures found in /dev/es

 Found Fibre Channel device(s): 
 Node WWN:2000000c50f1c8da Device Type:Disk device 
 Logical Path:/dev/rdsk/c1t1d0s2 
 Node WWN:2000000c50f1d9c9 Device Type:Disk device 
 Logical Path:/dev/rdsk/c1t0d0s2

注 - 使用しようとするとアッ、最後の行から1行をマージするだけです。

$ luxadm probe |awk '/Node/{n=$2}/Logical/{l=$2} END {print n,l}' 
 WWN:2000000c50f1d9c9 Path:/dev/rdsk/c1t0d0s2

予想される出力は次のとおりです。

WWN:2000000c50f1d9c9 Path:/dev/rdsk/c1t0d0s2
WWN:2000000c50f1c8da Path:/dev/rdsk/c1t1d0s2 

答え1

まだ言及されていない短い答えawk

awk '/Node/{n=$2; getline; print n " "$2; next}' filename
  • /Node/#パターンノードを見つけて、2番目のフィールドをn変数に保存します。n=$2
  • getline#次の行(Logical行が始まる場所)に移動して変数に保存されている内容を印刷し、次の行のn2番目のフィールドを印刷します。
  • next#現在のレコードの処理を中止し、次のレコードに移動します。

答え2

失敗したのは、キャプチャされた変数がブロック内で一度だけ印刷されるためですEND{}。これは最後の2つだけが印刷されることを意味します。 @Costasはすでによりエレガントなアプローチを提供していますが、いくつかの小さな変更で試したのと同じロジックを使用することもできます。

awk '{ if(/Node/){
        if(length(n)){print n,l} ## if we have an n, print them
        n=$2
        }
        if(/Logical/){l=$2}
      } 
        END {print n,l}' 

あるいは、他のツールを使用することもできます。

  1. GNU grep/パール

    luxadm probe |  grep -Po '^\s*(Node|Logical)\s*\K.*?(\s|$)' file | 
        perl -lne '$. % 2 ? printf : print'
    
  2. 真珠

    luxadm probe |  
      perl -ne 'chomp;if(s/.*(WWN:.*?)\s.*/$1 / || s/.*(Path:.*?)$/$1\n/){print}'
    

答え3

sed私はあなたが使用する必要があると思います。まず、一般的にパフォーマンスが優れており、awkこの場合は全体的に簡単なソリューションを提供します。

sed -n 'N;s/Node \([^ ]*\).*Logical/\1/p' <infile

...サンプルデータに基づいて印刷...

 WWN:2000000c50f1c8da Path:/dev/rdsk/c1t1d0s2
 WWN:2000000c50f1d9c9 Path:/dev/rdsk/c1t0d0s2

読み取った各行について、extsedもパターンスペースにN挿入された行区切り文字に追加されます。\nしたがって、上記のs///置換は2行にわたっており、一致するものがある場合はスペースで区切って2つのフィールドのみを印刷します。

上記sedの構文は、すべてのPOSIXシステムに完全に移植可能でなければなりません。

答え4

欲しいならawk

awk -v RS=' Node ' -v FS=' Logical Path:| ' '/WWN/{print $1,$6}'

その他(おそらくシンプル)

awk -F":| " '/Node/{printf "%s ", $3":"$4}/Logical Path/{print $4}'

残りとPath:

awk '/Node/{printf "%s ", $2}/Logical Path/{print $2}'

または

awk '/Node/{wwn=$2}/Logical Path/{print wwn,$2}'

sedそして最後にGNU:

sed -n '/WWN/{s/^\s*\S* *\|\( \S*\)\{3\}\s*$//g;N;s/\n\s*\S*//;p}'

関連情報