次のような構造を持つ大きなcsvファイルがあります。
334050049049426,2018-11-06T20:21:56.591Z,xxx,gdl-qns28-1540279057144
334050049049426,2018-11-06T21:32:47.431Z,xxx,gdl-qns19-1540278993723
334090015032064,2018-11-06T22:22:31.247Z,xxx,gdl-qns15-1540279009813
334090015032064,2018-11-07T01:44:11.442Z,xxx,gdl-qns25-1540279437614
334090015032064,2018-11-07T03:57:18.911Z,xxx,gdl-qns28-1540279710160
334050069888299,2018-11-07T03:32:12.899Z,xxx,gdl-qns29-1540279367769
334050069888299,2018-11-07T03:58:15.475Z,xxx,mgc-qns20-1540281468455
最初の列で見つかった重複値の最初の行を削除できるはずです。たとえば、行1、3、6を削除する必要があります。
答え1
awk
一意の最初の列を持つ行がない場合は、次を試してください。
awk -F, 'pre==$1 { print; next }{ pre=$1 }' infile
または通常、次のように変更します。
awk -F, 'pre==$1 { print; is_uniq=0; next }
# print when current& previous lines' 1st column were same
# unset the 'is_uniq=0' variable since duplicated lines found
is_uniq { print temp }
# print if previous line ('temp' variable keep a backup of previous line) is a
# uniq line (according to the first column)
{ pre=$1; temp=$0; is_uniq=1 }
# backup first column and whole line into 'pre' & 'temp' variable respectively
# and set the 'is_uinq=1' (assuming might that will be a uniq line)
END{ if(is_uniq) print temp }' infile
# if there was a line that it's uniq and is the last line of input file, then print it
コメントなしの同じスクリプト:
awk -F, 'pre==$1 { print; is_uniq=0; next }
is_uniq { print temp }
{ pre=$1; temp=$0; is_uniq=1 }
END{ if(is_uniq) print temp }' infile
メモ:これは、入力ファイルがinfile
最初のフィールドでソートされていると仮定します。そうでない場合は、ソートされたファイルを次のフィールドに渡す必要があります。
awk ... <(sort -t, -k1,1 infile)
答え2
csvの形式が正しいと仮定すると(引用符フィールド内にカンマや改行がなく、二重引用符"
(""
)がないなど)、次のようになります。
awk -F ',' 'NR==FNR{seen1[$1]++;next};seen1[$1]==1||seen2[$1]++
{print(NR,$0)}' infile infile
ファイルのどこで行が繰り返されるかを知る唯一の方法は、行が繰り返される回数を取得することです。これはで行われますseen1
。次に、行数が1(重複なし)または既に表示されている場合(ファイルの2番目のスキャン)(completeを使用seen2
)を印刷します。
ファイルソート済み最初のフィールドで@devWeekソリューションを使用してください。
答え3
$ cat file
1,a
2,b
2,c
3,d
3,e
3,f
4,g
4,h
5,i
「2,b」、「3,d」、「4,g」の行を削除しようとしています。
perl -F, -anE '
push $lines{$F[0]}->@*, $_
} END {
for $key (sort keys %lines) {
shift $lines{$key}->@* if (scalar($lines{$key}->@*) > 1); # remove the first
print join "", $lines{$key}->@*;
}
' file
1,a
2,c
3,e
3,f
4,h
5,i