順序に関係なく、行から複数​​のパターンを抽出します。

順序に関係なく、行から複数​​のパターンを抽出します。

私はUnixスクリプトが初めてなので、ご了承ください。

1行あたりのプロセスに関する情報を含むファイルを取得します。各行からこれらのプロセスに関する特定の情報を抽出する必要があります。

ファイルの例 -

process1 port=1234 appID=dummyAppId1 authenticate=true <some more params>
process3 port=1244 authenticate=false appID=dummyAppId2 <some more params>
process2 appID=dummyAppId3 port=1235 authenticate=true <some more params>

希望の出力は -

1
port=1234 authenticate=true appID=dummyAppId1 
2
port=1244 authenticate=false appID=dummyAppId2
3
port=1235 authenticate=true appID=dummyAppId3

各行の数字 1、2、3 は出力ファイルの行番号のみを表します。

コマンドを試してみましたが、sed s/順序によって異なり、入力ファイルのパラメータが順序に従っていません。したがって、入力ファイルの一部の行をスキップしました。

これが私の命令です -

sed -nr 'appId/s/(\w+).*port=([^ ]+) .*authenticate=[^ ]+) .*appId=[^ ]+) .*/\2\t\3\t\4/p' | sed =

順序に関係なく、これらのパラメータを抽出する方法を案内できる人はいますか?

ありがとうございます!

編集1:私はgrepの幅が0の後ろ姿アサーション機能をこのように使用できました。

grep -Po '(?<=pattern1=)[^ ,]+|(?<=pattern2=)[^ ,]+|(?<=pattern3=)[^ ,]+|(?<=pattern4=)[^ ,]+' filename

しかし、これは新しい行の各行の出力を提供するようです。

1234
true
dummyAppId1

grepを使用して1行に配置する方法を見つけようとしています(つまり、X行を1にマージしません)。

編集2:入力のパラメータ順序を混同する

編集3:申し訳ありません。前述したはずですが、perl私が作業しているコンピュータでは限られているようです。 StephaneとSundeepが提供した答えは、ローカルでテストしたときに完全に機能しましたが、最終的に実行するために必要なコンピュータでは機能しませんでした。 awk、grep、およびsedが主なサポートオプションであるようです。

ベストアンサー1

使用awk(テスト済みGNU awk、他の実装でも機能するかどうかわからない)

$ cat kv.awk
/appID/ {
    for (i = 1; i <= NF; i++) {
        $i ~ /^port=/ && (a = $i)
        $i ~ /^authenticate=/ && (b = $i)
        $i ~ /^appID=/ && (c = $i)
    }
    print NR "\n" a, b, c
}

$ awk -v OFS='\t' -f kv.awk ip.txt
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3


そしてperl

$ # note that the order is changed for second line here
$ cat ip.txt
process1 port=1234 authenticate=true appID=dummyAppId1 <some more params>
process3 port=1244 appID=dummyAppId2 authenticate=false <some more params>
process2 port=1235 authenticate=true appID=dummyAppId3 <some more params>

$ perl -lpe 's/(?=.*(port=[^ ]+))(?=.*(authenticate=[^ ]+))(?=.*(appID=[^ ]+)).*/$1\t$2\t$3/; print $.' ip.txt 
1
port=1234   authenticate=true   appID=dummyAppId1
2
port=1244   authenticate=false  appID=dummyAppId2
3
port=1235   authenticate=true   appID=dummyAppId3
  • (?=.*(port=[^ ]+))最初のキャプチャグループport
  • (?=.*(authenticate=[^ ]+))セカンドキャプチャグループauthenticateなど
  • print $.行番号について
  • 部分一致を回避するには、単語の境界が十分な場合はetcを使用してください\bport\bappIDそれ以外の場合は、(?<!\S)(port=[^ ]+)空間ベースの制限が使用されます。

含まれている行のみを印刷する必要があるappID場合、またはそのような条件が異なる場合は、次に-lpe変更し-lneて次にprint $.変更してください。print "$.\n$_" if /appID/

おすすめ記事