2017-02-08 7 views
-1

シェルスクリプトの新機能で、多くのタスクを実行する必要があります。私はできるだけ速く学ぶために努力していますが、シェルスクリプティングでは、タスクが非常に簡単に見えるし、他の時には私と一緒におもちゃを見ることもあります。そして私は今も同様の状況に直面している。 私はこのような出力を与えるコマンドを持っています。シェルスクリプト内でawkを使用して文字列を処理する方法

File     Dependents 
    ---------------------------------------------------------------------------- 
<File> is a requisite of <Dependents> 
Path: /usr/lib/obj 
    Java 1.0.0.0   analysis 0.0.0.2 
         runtime 1.2.0.0 
         client 1.2.0.0 
         framework 6.1.9.100 
         sguide 1.9.10.0 
         sysmgt 6.1.9.100 
         dsm 6.1.9.200 

Path: /etc/obj 
    Java 1.0.0.0   analysis 1.2.0.2 
         runtime 2.0.0.0 
         client3 6.1.9.0 
         sysmgt 6.1.9.0 
         dsm2 6.1.9.0 

ここで、今後の処理のために依存関係のリストを配列に追加したいと考えています。これは私がこれまでに行うことができる午前です:

<command> | cut -f1 | grep '[a-z]' | grep -v File | grep -v : | awk '{ print $1}' 

出力は次のようになります。

Java<<< I want this to be analysis 
runtime 
client 
framework 
sguide 
sysmgt 
dsm 

Java<<< want this to be analysis 
runtime 
client3 
sysmgt 
dsm2 

は、私は2つの別々の配列にこれら二つのリストをキャプチャする必要があります。

誰かがこの出力をエレガントな方法で達成するのに手伝ってもらえますか?私は、多くの条件と比較を含む私のブルートフォース方法でこのコードを洗うことを望んでいません。あなたが最初にJavaで部分文字列を削除することによって、あなたのソリューションを修正することができます

+0

あなたはawk配列を読み、最終的な 'awk'スクリプト(あなたのパイプライン上)にすべての処理を保存することをお勧めします。あなたの最終的な処理がどのように見えるかを知らなければ、それ以上のコメントや助けはありません。がんばろう。 – shellter

答えて

2

awkを救出します!

$ arr1=$(command ... | awk -v c=1 '!NF{f=0} f && s==c{print $1} /Java/{f=1; s++; if(s==c) print $(NF-1)}') 

$ arr2=$(command ... | awk -v c=2 '!NF{f=0} f && s==c{print $1} /Java/{f=1; s++; if(s==c) print $(NF-1)}') 

$ echo $arr1 
analysis runtime client framework sguide sysmgt dsm 

$ echo $arr2 
analysis runtime client3 sysmgt dsm2 

コマンドを1回実行して結果を2つの配列に分割したほうが良い場合があります。フィールドがない場合はFである場合

説明

awk -v c=1セットAWK変数C1に(グループインスタンス番号は説明)

'!NF{f=0}は(空行)は

f && s==c{print $1} fをリセットsetとcounterはcに等しい最初のフィールドを印刷する

/Java/{f=1; s++;パターンがJavaに一致した場合、fとインクリメントカウンタを設定し、 ...if(s==c) print $(NF-1)}'カウンタが一致する場合は、最後から2番目のフィールドを出力します。

+0

ありがとう。これはまさに私が探していたものです。 '!NF {f = 0} f && s == c {print $ 1}/Java/{f = 1; s ++; if(s == c)print $(NF-1)} ' これはマスターストロークですが、これまでデコードできませんでした。 – Albert

+0

私が理解したことは、最後の1フィールドを得るためにprint $(NF-1)}が使用され、残りの命令は開始条件と終了条件を得るためであるということです。あなたは詳細を教えてくれますか? – Albert

1

command | sed 's/Java [^ ]*//' | cut -f1 | grep '[a-z]' | grep -v File | grep -v : | awk '{ print $1}' 

あなたがawkを使用すると、あなたはより良いawkの完全な強さを使用することができます。ちょうどあなたが印刷に番号を持つ任意の行の最後から二番目のフィールドをしたいと言う:

command | awk '/[0-9]/ { print $(NF-1) }' 

これはsedを使用しようとしているよりも優れている(?あなたはタブやスペースを持っていない)

command | sed -n '/[0-9].[0-9]/ s/^.* \([^ ]*\) .*/\1/p' 

面白いですソリューションはrevを使用してテキストを元に戻します。そうすれば、cutは2番目のフィールドを見つけることができます。最後の行だけを読む人のために

command | grep '[0-9].[0-9]' | rev | cut -d " " -f2 | rev 

、私はawkソリューションを繰り返すことになります:

command | awk '/[0-9]/ { print $(NF-1) }' 
+0

多くの素晴らしい方法を提供してくれてありがとう。しかし、上記の1つは私の必要性に合っているので、私はそれを受け入れている – Albert

関連する問題