この問題に対するPerlまたはawkソリューションはありますか?

この問題に対するPerlまたはawkソリューションはありますか?

入力ファイルがあります(入力.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

気づく最初の行は実際のファイルの一部ではないので、明確にするためにここに追加します。

id1id2合計の値を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

おすすめ記事