ファイルの各行に 1 つ以上の値が存在する最小値のセットを探します。

ファイルの各行に 1 つ以上の値が存在する最小値のセットを探します。

次のファイルがありますdf

1   4
1   6
1   7
1   10
2   3
2   9
2   10
3   4
4   7
9   10

dfの各行にこれらの値の少なくとも1つが含まれるように、最小値のセットを決定する必要があります。

上記でdf期待するものはout次のとおりです。

1
2
4
9

動作するプロセスがありますが、非常に遅いです。このタスクをより速く実行したり、プロセスを並列化したりする方法はありますか?

x=1  
while [ $x -gt 0 ]  
do  
    i=$(paste df | tr '\t' '\n' | sort | uniq -c | 
        sort -r -k1,1 -k2,2n | awk 'NR==1{print $2}')  
    echo $i >> out  
    grep -vw $i df > tmpdf  
    cat tmpdf > df  
    x=$(paste df | wc -l)  
done

ベストアンサー1

以下は「ラインノイズ」Perlです。

perl -lane '
        for $f (@F) {push @{$x{$f}}, $.}                          # 1.
    } END {
        use List::Util qw/any first/;
        sub sort_by_count_desc {
            map  { $_->[0] } 
            sort { $b->[1] <=> $a->[1] || $a->[0] <=> $b->[0] } 
            map  { [$_, scalar(@{$x{$_}})] } 
            @_ 
        }
        @ordered = sort_by_count_desc(keys %x);                   # 2.
        %result = ();
        for ($i=1; $i<=$.; $i++) {                                # 3.
            $node = first { any {$_ == $i} @{$x{$_}} } @ordered;  # 4.
            $result{$node} = 1;
        }
        print join "\n", sort_by_count_desc(keys %result);
' df

どこ

  1. ファイルの行を繰り返し、各値をその値が表示される行のリストにマップします。
  2. シェイプリストのサイズに基づいて、降順にソートされた値のソートされた行を生成します。
  3. 行番号の範囲とforeach行番号を繰り返します。
  4. 行番号が表示される最初の値を見つける

この出力

1
2
4
10

おすすめ記事