web-dev-qa-db-ja.com

sed / awkを使用して必要な出力を取得する必要があります

Order:479959,60=20130624-09:45:02.046|35=D|11=884|38=723|21=1|1=30532|10=085|59=0|114=Y|56=MBT|40=1|43=Y|100=MBTX|55=/GCQ3|49=11342|54=1|8=FIX.4.4|34=388|553=2453|9=205|52=20130624-09:45:02.046|

Order:24780,100=MBTX|43=Y|40=1|34=388|553=2453|52=2013062409:45:02.046|9=205|49=11342|54=1|8=FIX.4.4|55=/GCQ3|11=405|35=D|60=20130624-09:45:02.046|56=MBT|59=0|114=Y|10=085|21=1|38=470|1=30532|

Order:799794,55=/GCQ3|49=11342|54=1|8=FIX.4.4|34=388|553=2453|9=205|52=2013062409:45:02.046|40=1|43=Y|100=MBTX|38=350|21=1|1=30532|10=085|59=0|114=Y|56=MBT|60=20130624-09:45:02.046|35=D|11=216|

Order:72896,11=735|35=D|60=2013062409:45:02.046|56=MBT|59=0|114=Y|10=085|1=30532|38=17|21=1|100=MBTX|43=Y|40=1|553=2453|9=205|52=20130624-09:45:02.046|34=388|8=FIX.4.4|54=1|49=11342|55=/GCQ3|

38=の後の番号と11=の後の番号を取得したいので、名前を変更する必要がありますClientid

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

Orderid-479959 38= 723 Clientid=884
Orderid-24780 38= 470 Clientid=405
Orderid-799794 38= 350 Clientid=216
Orderid-72896 38= 17 Clientid=735

どんな助けも感謝します。

4
Sonal

Awkを使用する

データがdata.txtというファイルにあると仮定して、script.awkというファイルを作成し、次の内容を指定します。

BEGIN { FS="[,|]" }
NF > 0 {
  for(i=1; i <= NF; i++) {
    split($i, f, "[:=]")
    map[f[1]] = f[2]
  }
  printf "Orderid-%s 38= %s Clientid=%s\n", map["Order"], map[38], map[11]
}

次に、次のコマンドを実行してデータを処理し、出力を取得します。

awk -f script.awk < data.txt

こちらもご覧ください

上記のコードでは、map変数は連想配列です。通常、他の言語(JavaのHashMap、RubyのHash、またはPythonの辞書)でマップと呼ばれるため、このマップを呼び出しました。

4
Sam Gleske

使用できます

sed -nr 's/Order:([0-9]+),.*[,\|]38=([0-9]+)[,\|].*/Orderid-\1 38= \2/p' file | tee file2

それから

sed -nr 's/.*[,\|]11=([0-9]+)[,\|].*/Clientid=\1/p' file | tee file3

それから

paste -d ' ' file2 file3

Stdoutで出力を取得します-必要に応じてリダイレクトします。

私はそれを一行で取得することはできません( 明らかに誰かができる11=および38=フィールドはどちらの順序でも構いません-ファイルを2回読み込む必要があります。次のようなスクリプトにロールできます。

#!/bin/bash
sed -nr 's/Order:([0-9]+),.*[,\|]38=([0-9]+)[,\|].*/Orderid-\1 38= \2/p' "$1" > file2
sed -nr 's/.*[,\|]11=([0-9]+)[,\|].*/Clientid=\1/p' "$1" > file3
paste -d ' ' file2 file3 > outfile
rm file2 file3

(これにより、プロセスで書き込むファイルがクリーンアップされ、最終出力がファイルoutfileに書き込まれます)

使用法:

  • スクリプトを空のファイルに貼り付けて保存します
  • 実行許可を与える:chmod u+x script
  • 入力ファイルの名前を引数として実行します:./script file
  • 変化する file2およびfile3現在のディレクトリにこれらの名前の既存のファイルがある場合は、スクリプトで!

説明

  • s/old/newoldnewに置き換えます
  • -r EREを使用
  • -n私たちが尋ねるまで印刷しない(これは空の行を取り出すだけだ)
  • [,\|]一致, ORリテラル|
  • ([0-9]+)後で保存するためのいくつかの数字
  • \1保存されたパターンへの後方参照
  • teeファイルに書き込み、stdoutに出力して確認できるようにします
  • > somefile出力をstdoutではなくsomefileにリダイレクトします
  • paste -d ' ' file2 file3区切り文字としてスペースを使用して、file2の列の後にfile3の列を貼り付けます。
  • rm file2 file3 file2とfile3を削除します
4
Zanna

ライナーの1つが常に良いとは限りません。

$ sed 's/[|,]\(11=[^|]*\).*\(|38=[^|]*|\).*/\2\1|/; s/Order:\([0-9]*\).*|38=\([0-9]*\).*|11=\([0-9]*\)|.*/Orderid-\1 38= \2 Clientid=\3/' foo
Orderid-479959 38= 723 Clientid=884
Orderid-24780 38= 470 Clientid=405
Orderid-799794 38= 350 Clientid=216
Orderid-72896 38= 17 Clientid=735

説明

  • s/old/new/oldnewに置き換えます
  • [|,]一致|または,
  • \(11=[^|]*\)は、|の後の11=を除く任意の数の文字に一致し、11=whateverとして後で使用するために\1を保存します
  • .*任意の数の任意の文字
  • \(|38=[^|]*|\)|38=whatever|として後で使用するために\2を保存します
  • \2\1|後方参照の置換(これにより、フィールドの一貫性が保たれるため、次のコマンドでそれらを処理できます)
  • ;は、シェルのようにコマンドを分離します
  • Order:\([0-9]*\).*|38=\([0-9]*\).*|11=\([0-9]*\)|.*はこのパターンに一致し(クリーンアップ済み)、\(parentheses\)で再利用したい部分を再び保存します
  • \(\)で保存した番号へのOrderid-\1 38= \2 Clientid=\3\1\2および\3後方参照による置換
3
muru

Perlソリューション:

ワンライナーとして:

Perl -a -F'[:|,]' -lne  'next if $_ =~ /^$/;printf("%sid-%s ",$F[0],$F[1]);foreach(@F){$t=$_ if $_ =~ "38=";$id=$_ if $_ =~ "11="};$id =~s/11=//;printf("%s Clientid=%s\n",$t,$id)' input.txt

またはスクリプトとして:

#!/usr/bin/env Perl
use strict;
use warnings;

open(my $fh,'<',$ARGV[0]) or die $!;

while(my $line = <$fh>){
    next if $line =~ /^$/;
    my @words  = split /[:|,]/,$line;
    printf("%sid-%s ",$words[0],$words[1]);
    my $t;
    my $id;
    foreach my $Word (@words){
        $t = $Word if $Word =~ "38=";
        $id=$Word if     $Word =~ "11=";
        $id =~ s/11=// if length($id);
    }
    printf("%s Clientid=%s\n", $t ,$id);
}
close($fh) or die $!;

試験結果:

$ ./parse_orders.pl ./input.txt                                                                                          
Orderid-479959 38=723 Clientid=884
Orderid-24780 38=470 Clientid=405
Orderid-799794 38=350 Clientid=216
Orderid-72896 38=17 Clientid=735
0