web-dev-qa-db-ja.com

grepの結果から、3列目に最小値を持つ行を見つける

このような行で構成されるファイルがあります(他の数字が含まれています)。これは、の出力の一部です

$ grep 1848 filename.csv

1848が1列目または2列目にある場合、.csvファイルで3列目が一番下の5行を見つけるにはどうすればよいですか?

1848,2598,11.310694021273559
1848,2599,10.947275955606203
1848,2600,10.635270124233982
1848,2601,11.916564552040725
1848,2602,12.119810736845844
1848,2603,12.406661156256154
1848,2604,10.636275056472996
1848,2605,12.549890992708612
1848,2606,9.783802450936204
1848,2607,11.253697489670264
1848,2608,12.16385432290674
1848,2609,10.30355814063016
1848,2610,12.102525596913923
1848,2611,11.636595992818505
1848,2612,10.741178028606866
1848,2613,11.352414275107423
1848,2614,12.204860161717253
1848,2615,12.959915468475387
1848,2616,11.320652192610872

残念ながら、3番目の列にも1848が表示されることがあるため、無視する必要があります。

6687,8963,9.241848677632822
6687,9111,10.537325656184889
6687,9506,11.315629894841848
5
Mona Jalal

GNUソートの場合:

grep -E '(^1848|^[0-9]{4},1848)' file | sort -t, -k3n | head -n 5

(最初の列の桁数が4桁未満または4桁を超える場合は、{4}+に置き換えてください)

出力:

1848,2606,9.783802450936204
1848,2609,10.30355814063016
1848,2600,10.635270124233982
1848,2604,10.636275056472996
1848,2612,10.741178028606866
8
Cyrus

awkだけで:

awk -F, 'BEGIN{PROCINFO["sorted_in"]="@ind_num_asc"} \
          $1==1848||$2==1848 {a[$3]=$0} END {for(i in a) print a[i]}' file.csv
  • BEGIN{PROCINFO["sorted_in"]="@ind_num_asc"}は、インデックスに従って、数字に従って、昇順で作成される配列の順序を設定します

  • $1==1848||$2==1848 {a[$3]=$0}は、1番目または2番目のフィールドが1848かどうかをチェックし、そうであれば、3番目のフィールド($3)が配列aインデックスとして取得され、値がレコード全体( $0

  • END {for(i in a) print a[i]}では、キーを繰り返して値を出力するだけです

5つのレコードのみを取得するには、head -5を最後に追加します。

awk ... | head -5

完全を期すために、breakループに小さなENDロジックを組み込むことで、最初の5つのレコードのみを取得できます。tailは不要です。

awk -F, 'BEGIN{PROCINFO["sorted_in"]="@ind_num_asc"} \
          $1==1848||$2==1848 {a[$3]=$0} END {j=0; for(i in a) \
           {print a[i]; j++; if(j==5) break}}' file.csv

例:

% cat file.txt
1848,2598,11.310694021273559
1848,2599,10.947275955606203
1848,2600,10.635270124233982
1848,2601,11.916564552040725
1848,2602,12.119810736845844
1848,2603,12.406661156256154
1848,2604,10.636275056472996
1848,2605,12.549890992708612
1848,2606,9.783802450936204
1848,2607,11.253697489670264
1848,2608,12.16385432290674
1848,2609,10.30355814063016
1848,2610,12.102525596913923
1848,2611,11.636595992818505
1848,2612,10.741178028606866
1848,2613,11.352414275107423
1848,2614,12.204860161717253
1848,2615,12.959915468475387
1848,2616,11.320652192610872

% awk -F, 'BEGIN{PROCINFO["sorted_in"]="@ind_num_asc"} $1==1848||$2==1848 {a[$3]=$0} END {for(i in a) print a[i]}' file.txt
1848,2606,9.783802450936204
1848,2609,10.30355814063016
1848,2600,10.635270124233982
1848,2604,10.636275056472996
1848,2612,10.741178028606866
1848,2599,10.947275955606203
1848,2607,11.253697489670264
1848,2598,11.310694021273559
1848,2616,11.320652192610872
1848,2613,11.352414275107423
1848,2611,11.636595992818505
1848,2601,11.916564552040725
1848,2610,12.102525596913923
1848,2602,12.119810736845844
1848,2608,12.16385432290674
1848,2614,12.204860161717253
1848,2603,12.406661156256154
1848,2605,12.549890992708612
1848,2615,12.959915468475387

% awk -F, 'BEGIN{PROCINFO["sorted_in"]="@ind_num_asc"} $1==1848||$2==1848 {a[$3]=$0} END {j=0; for(i in a) {print a[i]; j++; if(j==5) break}}' file.txt 
1848,2606,9.783802450936204
1848,2609,10.30355814063016
1848,2600,10.635270124233982
1848,2604,10.636275056472996
1848,2612,10.741178028606866
6
heemayl