2017-10-26 14 views
1

私はAS/400でこれをやっているという事実を私の質問に先立たせてください.IBMはユーティリティを最新に保っています。私は/[a-AA-Z0-9]*.LIB/のようなパターンを抽出したいが、見つかった2番目のパターンを抽出したい。以下の2つのパスがどのように異なるかを見てください:テキストの行から2番目のパターンを抽出する方法は?

/QSYS.LIB/KDBDFC1_5.LIB/AUTNOTMAIN.PGM 
/DATADEV/QSYS.LIB/FPSENGDEV.LIB/AUTNOTMAIN.PGM 

ので、この場合には、私はKDBDFC1_5.LIBとFPSENGDEV.LIB、ないQSYS.LIBをしたいです。

gawkをmatch()関数で使用して配列に格納しようとしましたが、match()でmatch()に3つの引数を指定することはできません。 gawkのバージョンは3.0.3です。うん。私はコマンドラインの設定でこの作業をしようとすると、perlでふざけています。 Perlのバージョンは5.8.7です。あなたの答えにはgrepのいくつかの新しいオプションが含まれていれば、それが何であるか分かっていれば、PASEユーティリティもありますが、grepのQSHバージョンも同様に古いと考えるかもしれません。

私はまだこの1つを強く叩いていますが、すぐに頭痛を抱く可能性があるので、どんな提案もありがとうと思います。 :-)

+0

幸いにも、IBM iの最新の技術リリースには、bashと、aixの亜種では欠けているか、うまく機能しない多くのgnuツールが含まれています。もちろん、古いAS400 ;-)をアップグレードする必要があります – jmarkmurphy

答えて

2

おそらくlast-1セグメントが必要です。 awkに続いて、動作するはずです:

awk -F/ '{print $(NF-1)}' file 

KDBDFC1_5.LIB 
FPSENGDEV.LIB 

それとも、おそらくこのawk.LIBとプリント2ndフィールドを検索することによって動作します:

awk -F'.LIB' '{print substr($2,2) FS}' file 

KDBDFC1_5.LIB 
FPSENGDEV.LIB 
+1

本当に最後の1セグメントが必要です。私はその方向では考えなかった。 –

+1

フィールドセパレータとして部分文字列全体を使用することについても私は考えていませんでした。 –

1

をどの程度

perl -lne '@matches = /(\w+\.LIB)/g; print $matches[1] if @matches > 1' file 
+0

これも同様に機能します。 –

0

リターン<word>.LIBsecond出現:

perl -pe 's/^(?:.*?\.LIB).*?([\w_.]*.LIB).*$/\1/g' 

リターン<word>.LIBlast出現:

perl -pe 's/^(?:.*\.LIB).*?([\w_.]*.LIB).*$/\1/g' file 


^ .LIB を含む
(?:.*\.LIB)未捕獲基
.*? anythings ungreedy
([\w.]*.LIB)最初のキャプチャグループ 貪欲<word>.LIB
.* anythingsと開始

1

によって$仕上げmatchは、アレイ出力をサポートしていない場合は、あなたが最初の試合を破棄し、二回のマッチング、および第二の印刷を実行することができます:だから

$ awk '{p="[a-zA-Z0-9_]*.LIB"; sub(p,""); match($0,p); print substr($0,RSTART,RLENGTH)}' file 
KDBDFC1_5.LIB 
FPSENGDEV.LIB 
0

を...検索にアンダースコアを追加した後正規表現は、私のために働い以下:

01:もちろん

sed 's/.*\/\([[:alnum:]_]*\.LIB\).*/\1/' file 

、あなたはまた、代わりに、複雑な正規表現の書き換えのgrep -oでこれを行うことができます

grep -o '[[:alnum:]_]*\.LIB' file | awk 'NR%2==0' 

これらはPOSIX互換機能しか使用しないため、OS/400では問題ありません。

awk '{sub(/.*QSYS\.LIB\//,""); sub(/\/.*/,"")}1' file 

あなたはQSYS.LIBは、あなたがライン上で、以前存在し得る避けるためにしようとしているものであることがわかっている場合は、これが行う可能性があります:それはあなたがそう、awkの中で、この探している、と述べました。そして、それは本当にあなたが望む2つの.LIBファイルのであれば、これが行う可能性があります:

awk '{match($0,/[[:alnum:]_]+\.LIB/); s=substr($0,RSTART+RLENGTH); match(s,/[[:alnum:]_]+\.LIB/); print substr(s,RSTART,RLENGTH)}' file 

あるいは、読みやすい勃発を:

awk '{ 
    match($0,/[[:alnum:]_]+\.LIB/); 
    s=substr($0,RSTART+RLENGTH); 
    match(s,/[[:alnum:]_]+\.LIB/); 
    print substr(s,RSTART,RLENGTH) 
}' file 

これが唯一のプレーン古いAWKを使用しています関数match()substr()は、(1)最初の.LIBを取り除いて残りの行を一時変数に格納し、(2)その変数の中で次の.LIBを見つけます。

これは、物事の特定の位置に依存しないという利点があります。つまり、「面白い」ファイルが最初のファイルの直後であるとは見なされません。

これは厄介で、anubhavaの第2の解決策ははるかに優雅だと言いました。 :-)

関連する問題