入力ファイル(入力.txt)を以下のように入力します。
id1 id2 name weight
53723848 12651711 timburnes 1.36667
53530214 12651711 timburnes 1.51191
53723848 53530214 timburnes 1.94
764157 52986038 ericcartman 0.861145
56797854 764157 ericcartman 1.35258
56797854 52986038 ericcartman 1.73781
ご了承ください最初の行は実際のファイルの一部ではありませんが、わかりやすくするためにここに追加しました。。
id1
との値をid2
2つの別々のファイルに抽出しようとしています。ユニーク.txtそして重複.txt。
weight
列の値が1.5より大きい場合は、重複したIDこの場合、値をファイルid1
に移動し、値をファイルに移動します。unique.txt
id2
duplicate.txt
重みの列が1.5未満の場合、重複した値がないことを意味します。この場合、とid1
のid2
両方を ユニーク.txtファイル。
したがって、上記の入力に対して、次のような出力が期待されます。
のためにユニーク.txtファイル、
53723848 timburnes
764157 ericcartman
56797854 ericcartman
のために重複.txtファイル、
12651711 timburnes
53530214 timburnes
52986038 ericcartman
以下のコードを使用して重複を見つけることができます。
4列目に基づいて1.5より大きい値を取得するには、
awk -F" " '$4 >= 1.5 { print $1" " $2" " $3" " $4}' file1.txt > Output.txt
ここで、値が 1.5 より大きい場合は、以下のコードを使用して、名前に基づいて重複する ID をマージできます。
perl -ane 'foreach(@F[0..1]){$k{$F[2]}{$_}++}
END{
foreach $v (sort keys(%k)){
print "$_ " foreach(keys(%{$k{$v}}));
print "$v\n"
};
} ' Output.txt
しかし、上記のアプローチでは、希望どおりの出力を得ることができません。
編集:
以下のように入力してコマンドを実行しています。
awk '{
if ($4 > 1.5) {
if (++dup[$2] == 1) print $2, $3 > "duplicate.txt"
}
else
if (++uniq[$1] == 1) print $1, $3 > "unique.txt"
}' << END
17412193 43979400 ericcartman 2.16667
21757330 54678379 andrewruss 0.55264
END
出力は次のようになります。
-bash-3.2$ cat unique.txt
21757330 a.andreev
-bash-3.2$ cat duplicate.txt
43979400 ericcartman
しかし、私が期待している出力は、
cat unique.txt
17412193 ericcartman
21757330 andrewruss
54678379 andrewruss
cat duplicate.txt
43979400 ericcartman
答え1
解決策は次のとおりですawk
:
$ awk '
$4 < 1.5 {
uniq[$1] = $3;
uniq[$2] = $3;
next;
}
{
uniq[$1] = $3;
dup[$2] = $3;
delete uniq[$2];
}
END {
print "--unique.txt--";
for(i in uniq) {
print i,uniq[i]
}
print "";
print "--duplicate.txt--";
for(i in dup) {
print i,dup[i]
}
}' file
--unique.txt--
764157 ericcartman
56797854 ericcartman
53723848 timburnes
--duplicate.txt--
53530214 timburnes
52986038 ericcartman
12651711 timburnes
2番目の例:
$ awk '
$4 < 1.5 {
uniq[$1] = $3;
uniq[$2] = $3;
next;
}
{
uniq[$1] = $3;
dup[$2] = $3;
delete uniq[$2];
}
END {
print "--unique.txt--";
for(i in uniq) {
print i,uniq[i]
}
print "";
print "--duplicate.txt--";
for(i in dup) {
print i,dup[i]
}
}' << END
> 17412193 43979400 ericcartman 2.16667
> 21757330 54678379 andrewruss 0.55264
END
--unique.txt--
21757330 andrewruss
54678379 andrewruss
17412193 ericcartman
--duplicate.txt--
43979400 ericcartman
答え2
$ awk '{
if ($4 > 1.5) {
if (++dup[$2] == 1) print $2, $3 > "duplicate.txt"
}
else
if (++uniq[$1] == 1) print $1, $3 > "unique.txt"
}' << END
53723848 12651711 timburnes 1.36667
53530214 12651711 timburnes 1.51191
53723848 53530214 timburnes 1.94
764157 52986038 ericcartman 0.861145
56797854 764157 ericcartman 1.35258
56797854 52986038 ericcartman 1.73781
END
$ cat unique.txt
53723848 timburnes
764157 ericcartman
56797854 ericcartman
$ cat duplicate.txt
12651711 timburnes
53530214 timburnes
52986038 ericcartman
答え3
以下は Perl の例です:
perl -lane '$F[3]>1.5 ? print STDERR "$F[1] $F[2]" : print STDOUT "$F[0] $F[2]"'\
input.txt 2> duplicate.txt > unique.txt
ここでは重複をチェックしていません。質問を正しく理解していれば、すでに重複をチェックしており、重複しているかどうかは最後のフィールドの値によって決まります。私が誤解している場合はお知らせください。更新します。
上記のコードは
$ cat duplicate.txt
12651711 timburnes
53530214 timburnes
52986038 ericcartman
$ cat unique.txt
53723848 timburnes
764157 ericcartman
56797854 ericcartman