2つのファイル間で順次置換された行のインデックスを抽出します。

2つのファイル間で順次置換された行のインデックスを抽出します。

タブで区切られた2つの大きなファイル(> 10 GB)があり、並べ替えるとその内容が同じであることがわかります。

Sourceただし、同じ「キー」(ここでキーは列に基づいてグループ化されたLocation行として定義されています)を共有するときに、行の順序と置き換えられた行のインデックスに興味があります。

つまり、これら2つのファイル間の行は、同じグループに属している場合にのみ(つまり、同じソースと場所を共有する場合)、互いに比較する必要があります。

たとえば、次の例では、行4、5、6をfile1.tsv次の行4、5、6と比較する必要があります。file2.tsv

注:ファイルは通常のTSVです。より見やすくするために、ここに余分なスペースを追加し、列を中央に揃えて右に揃えます。このスペースは元のファイルの一部ではありません。

ファイル1.tsv

     Identifier  Position Source  Location
     AY1:2301        87    ch1        14
    BC1U:4010       105    ch1        14
    AC44:1230        90    ch1        15
    AJC:93410        83    ch1        16
    ABYY:0001       101    ch1        16
       ABC:01        42    ch1        16
      HH:A9CX       413    ch1        17
      LK:9310         2    ch1        17
    JFNE:3410       132    ch1        18
    MKASDL:11        14    ch1        18
   MKDFA:9401        18    ch1        18
  MKASDL1:011       184    ch2        50
   LKOC:AMC02        18    ch2        50
     POI:1100       900    ch2        53
    MCJE:09HA        11    ch2        53
   ABYCI:1123        15    ch2        53
     MNKA:410         1    ch2        53

ファイル2.tsv

     Identifier  Position Source  Location
     AY1:2301        87    ch1        14
    BC1U:4010       105    ch1        14
    AC44:1230        90    ch1        15
       ABC:01        42    ch1        16
    ABYY:0001       101    ch1        16
    AJC:93410        83    ch1        16
      HH:A9CX       413    ch1        17
      LK:9310         2    ch1        17
    MKASDL:11        14    ch1        18
    JFNE:3410       132    ch1        18
   MKDFA:9401        18    ch1        18
  MKASDL1:011       184    ch2        50
   LKOC:AMC02        18    ch2        50
     MNKA:410         1    ch2        53
     POI:1100       900    ch2        53
   ABYCI:1123        15    ch2        53
    MCJE:09HA        11    ch2        53

「diff」に似ていますが、「グループ」レベルで実行したいです(行がSource同じ合計を共有している場合にのみ比較されますLocation)。

抽出したいオリジナル同じ「ソース/位置」内で行の順序が「交換」されると、「行番号」グループ「(またはキー)。

行全体の内容が一致する必要があります。

しかし、どうすればいいのかわかりません。私が考えることができるのはforループを書くことだけです。これは、元のデータセットに数百万の行がある場合、非常に非効率的です。

予想される結果:

Group_Source:Location  df1.index  df2.index

ch1:16                         4          6
ch1:16                         6          4
ch1:18                         9         10
ch1:18                        10          9
ch2:53                        14         15
ch2:53                        15         17
ch2:53                        17         14

仮定:

  • 両方のデータフレームは同じ数の行を持ちます。
  • 両方のデータフレームは同じです(行の順序のみが変わるため、両方ともソース基準、位置基準、位置基準、識別子基準でソートされている場合はまったく同じです)。
  • 「交換された」行は、常にすべての列の内容と正確に一致します。

ベストアンサー1

入力ファイルのサイズのため、これは私が使用できるまれなケースの1つなので、getline> 10Gの代わりに一度に数行だけメモリに保存します。

$ cat tst.awk
BEGIN {
    OFS = "\t"
    print "Group_Source:Location", "df1.index", "df2.index"
}
NR != FNR { exit }
{ srcLoc = $3 ":" $4 }
srcLoc != prevSrcLoc {
    if ( NR > 1 ) {
        diff()
    }
    prevSrcLoc = srcLoc
}
{
    file1[$1,$2] = FNR - 1
    if ( (getline < ARGV[2]) > 0 ) {
        file2[$1,$2] = FNR - 1
    }
}
END { diff() }

function diff(          idPos) {
    for ( idPos in file1 ) {
        if ( file1[idPos] != file2[idPos] ) {
            print prevSrcLoc, file1[idPos], file2[idPos]
        }
    }
    delete file1
    delete file2
}

$ awk -f tst.awk file1.tsv file2.tsv
Group_Source:Location   df1.index       df2.index
ch1:16  6       4
ch1:16  4       6
ch1:18  10      9
ch1:18  9       10
ch2:53  17      14
ch2:53  15      17
ch2:53  14      15

もっと情報がgetline欲しいなら読んでくださいhttp://awk.freeshell.org/AllAboutGetline

Identifier上記のコードは、2つのファイル間の4つのフィールドをすべて比較するため、入力中および/または繰り返される場合にも機能します。Position例の入力に示すように、ソースとロケーションの値が2つのファイル間で同じ順序であるとします。

おすすめ記事