![大きなファイルから最初のフィールド/列が重複している行を削除する](https://rvso.com/image/164735/%E5%A4%A7%E3%81%8D%E3%81%AA%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E6%9C%80%E5%88%9D%E3%81%AE%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%2F%E5%88%97%E3%81%8C%E9%87%8D%E8%A4%87%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E8%A1%8C%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B.png)
非常に大きなファイルがあります (以下のスニペット)。最初の列の数字が上の行から連続して増加しない行を削除する必要があります。
たとえば、最初の列の識別子が「40812
」であるスニペットの最初の行を保持します。次に、40813
最初の列に「 」がある行 (この例では行 3) を保持し、次に「 」で始まる行40814
などを保持します。2 行目など、この連続性に違反する行はすべて削除します。
これまでの質問/回答で解決策を探してみましたが、今のところ成功していません。いくつかの質問で紹介されている解決策は次のとおりです。
awk -F',' ' '!seen[$1]++ myFile
私は次のように考えた別の解決策を採用しました。
sort -t':' -k 1,1 -u myFile
どこが間違っているのか教えていただけるとありがたいです。私はファイル操作の経験があまりありません。
40812 20406.000000 0.843859468 1083.209050130 -994.562279080 -993.349611938 22.120868921
40829 20414.500000 0.891283743 1144.084593627 -994.539001565 -993.349739827 21.177788019
40813 20406.500000 0.829362077 1064.599666089 -994.546948121 -993.348764740 22.087239027
40830 20415.000000 0.889606427 1141.931529727 -994.537943593 -993.350242614 21.282490969
40814 20407.000000 0.822524589 1055.822814442 -994.540118434 -993.348757318 22.083606005
40831 20415.500000 0.875230513 1123.478077086 -994.523844766 -993.350421831 20.606467962
40815 20407.500000 0.823511602 1057.089780943 -994.541681744 -993.349315083 22.432111979
40832 20416.000000 0.846150258 1086.149592126 -994.494220141 -993.349798791 22.309054136
40816 20408.000000 0.824550451 1058.423286012 -994.543159511 -993.349731194 22.481428146
40833 20416.500000 0.811604775 1041.805740021 -994.458563132 -993.348626225 21.118428946
40834 20417.000000 0.787796672 1011.244783236 -994.434062658 -993.347887110 20.963790894
40817 20408.500000 0.819160081 1051.504008955 -994.537767061 -993.349702160 22.268819809
40835 20417.500000 0.784857495 1007.471947645 -994.431441227 -993.348167742 20.731789112
40818 20409.000000 0.807571275 1036.628191427 -994.525675417 -993.349169067 22.332761049
40836 20418.000000 0.799208319 1025.893192994 -994.446595759 -993.348938468 21.268665075
40819 20409.500000 0.797104599 1023.192780242 -994.514563564 -993.348491176 22.622548103
40837 20418.500000 0.819797939 1052.322786256 -994.467698852 -993.349417295 21.013041973
40820 20410.000000 0.796605925 1022.552664951 -994.513928312 -993.348319789 22.193170071
答え1
これはまさに次のような点awk
で優れています:
$ awk '{ if(NR==1 || $1 == last+1){print; last=$1}}' file
40812 20406.000000 0.843859468 1083.209050130 -994.562279080 -993.349611938 22.120868921
40813 20406.500000 0.829362077 1064.599666089 -994.546948121 -993.348764740 22.087239027
40814 20407.000000 0.822524589 1055.822814442 -994.540118434 -993.348757318 22.083606005
40815 20407.500000 0.823511602 1057.089780943 -994.541681744 -993.349315083 22.432111979
40816 20408.000000 0.824550451 1058.423286012 -994.543159511 -993.349731194 22.481428146
40817 20408.500000 0.819160081 1051.504008955 -994.537767061 -993.349702160 22.268819809
40818 20409.000000 0.807571275 1036.628191427 -994.525675417 -993.349169067 22.332761049
40819 20409.500000 0.797104599 1023.192780242 -994.514563564 -993.348491176 22.622548103
40820 20410.000000 0.796605925 1022.552664951 -994.513928312 -993.348319789 22.193170071
あるいは、ちょっとゴルフをしてみましょう:
$ awk '(NR==1 || $1 == last+1) && last=$1' file
40812 20406.000000 0.843859468 1083.209050130 -994.562279080 -993.349611938 22.120868921
40813 20406.500000 0.829362077 1064.599666089 -994.546948121 -993.348764740 22.087239027
40814 20407.000000 0.822524589 1055.822814442 -994.540118434 -993.348757318 22.083606005
40815 20407.500000 0.823511602 1057.089780943 -994.541681744 -993.349315083 22.432111979
40816 20408.000000 0.824550451 1058.423286012 -994.543159511 -993.349731194 22.481428146
40817 20408.500000 0.819160081 1051.504008955 -994.537767061 -993.349702160 22.268819809
40818 20409.000000 0.807571275 1036.628191427 -994.525675417 -993.349169067 22.332761049
40819 20409.500000 0.797104599 1023.192780242 -994.514563564 -993.348491176 22.622548103
40820 20410.000000 0.796605925 1022.552664951 -994.513928312 -993.348319789 22.193170071
説明
if(NR==1 || $1 == last+1)
: はNR
現在の行番号です。したがって、NR == 1
ファイルの最初の行を読み取っている間のみ true になります。常に最初の行を印刷するためにこれが必要です。次に、行の最初のフィールド ( ) が変数に格納されている値に 1 を加えた値に等しい$1 == last +1
場合、は true になります。まとめると、これは「これが最後の行であるか、最初のフィールドが last + 1 に等しい場合」を意味し、ターゲット行を定義します。$1
last
print; last=$1
: 上記の2つの条件のいずれかが真の場合、行を出力し、の値をのlast
最初のフィールドに設定します。これ次の行を処理できるようにします。