特定の文字列を見つけるときに最も近い列を印刷する方法

特定の文字列を見つけるときに最も近い列を印刷する方法

約12000行のファイルがあります。

pk=91001011964;fck=85;fcv=true;fpi=1;fci=cacf;fmd=1422745568,;fck=83;fcv=decoccm;fpi=1;fci=cacf;fmd=1423070648,;fck=87;fcv=false;fpi=1;fci=cacf;fmd=1422745568,;fck=86;fcv=true;fpi=1;fci=cacf;fmd=1422745568,;fck=35;fcv=54bed48ad84397433fef0a350d65a893;fpi=1;fci=cacf;fmd=1422745568,;fck=83;fcv=travide;fpi=1;fci=cacf;fmd=1422811693,;fck=88;fcv=true;fpi=1;fci=cacf;fmd=1422745568,;fck=84;fcv=10;fpi=1;fci=cacf;fmd=1422745568;vpi=ppi=1;pci=cacf;pmd=1423070648;pos=null;pod=0;pso=null;psd=0;vos=null
pk=91001045537;fck=86;fcv=true;fpi=1;fci=cacf;fmd=1421428238,;fck=85;fcv=true;fpi=1;fci=cacf;fmd=1421428238,;fck=87;fcv=false;fpi=1;fci=cacf;fmd=1421428238,;fck=88;fcv=true;fpi=1;fci=cacf;fmd=1421428238,;fck=84;fcv=10;fpi=1;fci=cacf;fmd=1421428238,;fck=35;fcv=cd9b9ed4fc167d8007dd9544114bc83f;fpi=1;fci=cacf;fmd=1421428238,;fck=83;fcv=demelog;fpi=1;fci=cacf;fmd=1421557377;vpi=ppi=1;pci=cacf;pmd=1421557377;pos=null;pod=0;pso=null;psd=0;vos=null   
pk=91001440737;fck=86;fcv=true;fpi=1;fci=cacf;fmd=1421687966,;fck=85;fcv=true;fpi=1;fci=cacf;fmd=1421687966,;fck=87;fcv=true;fpi=1;fci=cacf;fmd=1421687966,;fck=88;fcv=true;fpi=1;fci=cacf;fmd=1421687966,;fck=84;fcv=10;fpi=1;fci=cacf;fmd=1421687966,;fck=35;fcv=7360072ca14cb5d5578a3902fbe51792;fpi=1;fci=cacf;fmd=1421687191;fck=78;fcv=de724a544277d79c14d19809fe51ab71;fpi=1;fci=cacf;fmd=1421687966,;fck=83;fcv=demelog;fpi=1;fci=cacf;fmd=1421816564;vpi=ppi=1;pci=cacf;pmd=1421816564;pos=null;pod=0;pso=null;psd=0;vos=null

ファイルを解析し、行内で特定の順序で特定の文字列値を見つけて、その行に最も近い列を印刷または選択する必要があります。文字列値がない場合は、空の列が印刷されます。

私が持っていると仮定しますfck=35。存在する場合は、検索された文字列に最も近いfmdを印刷します。行3の場合になりますfck=35;fmd=1421687191fck=35存在しない場合は、空の列を追加するだけです。fck=35;;

私が世話をしているとしましょうfck=78。存在する場合は、検索された文字列に最も近い fmd を印刷します。 3行にはがあり、fck=78;fmd=1421687966なければfck=78空の列を追加してfck=78;;

その他の条件は次のとおりです。

For fck=84 look for the next fcv For fck=85 look for the next fcv For fck=86 look for the next fcv For fck=83 look for the next fcv fck=83 の次の fcv は naismc、decoide、decccm、travide、travccm、または mariccm です。

たとえば、3行目を使用します。

fck=35;fmd=1421687191;fck=78;fmd=1421687966;fck=84;fcv=10;fck=85;fcv=true;fck=86;fcv=true;fck=83;fcv=demelog

または(fmdまたはfcvがない場合、または少なくとも一部が欠落している場合:この部分はもう3行ではなく、例に入れていないもう1つだけですが、問題ではないようです)

fck=35;;fck=78;;fck=84;fcv=10;fck=85;fcv=true;fck=86;;fck=83;fcv=demelog

私はawkこれをやってやろうと思いますsed。しかし、それがどれほど強力かは疑わしく、今まで見たところによると役に立ちません。おそらくPythonはこれを行うことができます。しかし、私はPythonに初めて触れました。

どんな助けでも歓迎します。

私の友人がこの問題を解決するのを助けました。

awk -F\; -v fck=78 '{for (i=1;i<=NF;i++) if($i=="fck="fck) print "fck="fck";"$(i-1)}' name_of_the_file

ご覧のように、上記のすべての条件を満たす必要がある場合は、fck = 78という1つの条件のみが必要です。

この小さなスクリプトを改善する方法や変更を加えることができるすべてのことについてのヒントがあれば良いでしょう。しかし、他のスクリプトも可能です。 Pythonを検討していますが、どうすればいいかわかりません。

ティア

ベストアンサー1

探しているさまざまな文字列を含むファイルがあるとします。このような:

fck=35 fmd
fck=78 fcv
bnv=12 fcv

これらのそれぞれについてファイルを検索し、行がパターンと一致する場合は、文字列の後のfmd最初の値と一致する必要があります。もしそうなら、Perlで次のようにします。

#!/usr/bin/env perl

## Open the list of search patterns.
## The script expects it to be the 1st argument.
open(my $list,"$ARGV[0]");
## Read the file and save the patterns
## in the %pat hash.
while (<$list>) {
    ## remove trailing newlines
    chomp;
    ## separate the search pattern from the target
    my @fields=split(/\s+/);

    ## Save the search pattern and accompanying target in
    ## in the hash (%pats). 
    $pats{$fields[0]}=$fields[1];
}

## Open the list of search patterns.
## The script expects it to be the 2nd argument.
open(my $file,"$ARGV[1]");

## Read the file
while (<$file>) {
    ## split the line on ';' into the @fields array
    my @fields=split(/;/);

    ## This is the string that will be printed for
    ## the current line.
    my $outstring="";
    ## Check each of the search patterns against
    ## each of the fields.
    foreach my $pat(keys(%pats)) {
        ## Add the pattern to the outstring
        $outstring.="$pat;";
        ## save all all 1st fmd values that follow
        ## this pattern. 
        my @matches= ( /$pat.+?($pats{$pat}=[^;]+)/g );
        ## Add this pattern's matches to the output string.
        $outstring.= join(";",@matches) . ";";
    }
    ## Print the output string for this line
    print "$outstring\n";
}

たとえば、上記のスクリプトをparser.plファイルに保存し$PATHて実行可能にしたら、chmod 755 ~/bin/parser.pl次のように実行できます。

$ parser.pl list.txt file.txt 
bnv=12;;fck=35;fmd=1422745568,;fck=78;;
bnv=12;;fck=35;fmd=1421428238,;fck=78;;
bnv=12;;fck=35;fmd=1421687191 fmd=1111111111;fck=78;fcv=de724a544277d79c14d19809fe51ab71;

おすすめ記事