列内の一致する文字列の数に基づいて列を削除します。

列内の一致する文字列の数に基づいて列を削除します。

列(行数が異なる列)に=> $ {MaxAllowedNumberOfFs} 'Fがある場合は、テキストファイル内のすべての列を削除するにはコマンドが必要です。

近い疑似コードがありますが、一致回数制限を設定する方法がわかりません。

リミッタが 3 に設定されていると仮定すると、入力ファイルの例は次のようになります。

F G F H H
G F F F A
F G F F F
F F F T F

その後、希望の出力は次のようになります。

G H H
F F A
G F F
F T F

擬似コードを閉じる(リミッターはファイルによって変更され、変更される可能性があります):

MaxAllowedNumberOfFs="1012"

Count_of_columns=`awk '{print NF}' filename | sort -nr | sed -n '$p'` 

for((i=1;i<=$Count_of_columns;i++)); do awk -v i="$i" -v x="$MaxAllowedNumberOfFs" '$i == F =>x number of times {$i="";print $0}' filename; done

明らかに、grepを使用してすべての列を繰り返すことができ、列の発生回数を計算し、基準を満たさない列を削除できました。しかし、本当に遅いです。本当に良いawkコマンドが欲しいのですが、awkスキルはありません。

答え1

1つの方法は、ファイルを2回読み取ることです。最初はFが計算され、2番目はラインが出力されます。そのように

#!/bin/sh

awk -v n=3 '
        NR==FNR { for (i=1;i<=NF;i++) { if ($i == "F") { c[i]++ }} ;next }                                                                            
        { for (i=1;i<=NF;i++) { if (c[i] < n) { printf("%s ", $i) } } ;printf("\n") }                                                                 

' filename filename

NR==FNRファイルを読むことが今回が最初か2番目かを区別するコツは次のとおりです。これは、ファイルに行があると想定し、ファイルを初めて読み取った場合にのみ適用されます。配列は、c列内のF文字の数です。nextファイルを初めて読み取ったときに、この行のすべての処理が完了したことを示します。 2行目は、ファイルを2回目に読み込むと実行されます。

答え2

これは説明です移転 - ラインフィルタ - 移転方法。あなたの(大容量ファイル)状況には適していないかもしれませんが、他の人にとって価値があるかもしれません。

$ cat file
F G F H H
G F F F A
F G F F F
F F F T F

それから

$ rs -T < file | perl -alne 'print unless (grep { $_ eq "F" } @F) > 3' | rs -T
F  G  H  H
G  F  F  A
F  G  F  F
F  F  T  F

答え3

以下のスクリプトをお試しください。素晴らしい作品。

for ((i=1;i<=5;i++)); do c=`awk -v i="$i" '{print $i}' o.txt|awk '$1=="F" {print $0}'| sed -n '/F/{;=;p}'| sed "N;s/\n/ /g"| sort -k1 -rn|sed -n '1p'| awk '{print $1}'`; if [[ $c -lt 3 ]]; then awk -v i="$i" '{print $i}' o.txt >file_$i; fi; done

paste  file_*

出力

G H H
F F A
G F F
F T F

関連情報