1

マージしたい表形式のファイルが 2 つありますが、その前に 2 番目のファイルを削減したいと考えています。

最初のファイルは File1 が表形式で、次のようになっているとしましょう

 A 67 98 56
 A 22 29 62
 A 11 99 28
 B 37 88 14
 B 33 99 65

A には 3 つの線があり、B には 2 つの線があります

File2 には A と B の間に 3000 行が含まれています。File2 から行をランダムに選択したいのですが、File1 とまったく同じ数の A と B を選択します。つまり、A のランダムな行は 3 行、B の行は 2 行だけです。

awk でこれを行う方法について考えている人はいますか?

ありがとう

4

2 に答える 2

1
#!/bin/bash
read -r acount bcount <<< $(csplit file2 '/^B /')

awk -v "acount=$acount" -v "bcount=$bcount" '
    NR == FNR {
        arr[$1]++; 
        next
    }
    ! setup {
        setup = 1
        while (arandcount < acount) {
            line = int(rand() * acount) + 1
            if (! alines[line]) {
                alines[line] = 1
                arandcount++
            }
        }
        while (brandcount < bcount) {
            line = int(rand() * bcount) + 1
            if (! blines[line]) {
                blines[line] = 1
                brandcount++
            }
        }
    }
    FILENAME == "xx00" && FNR in alines {
        print
    }
    FILENAME == "xx01" && FNR in blines {
        print
    }' file1 xx00 xx01

「xx00」と「xx01」は、によって作成されたファイルの名前ですcsplit

このcsplitコマンドは、入力ファイルを正規表現で分割し、各出力ファイルの行数を出力します。このreadコマンドは、それらのカウントを変数に入れます。変数は AWK プログラムに渡されます。

最初のブロックは、file1 のすべての行を読み取り、各「タイプ」(A または B) をカウントします。

2 番目のブロックは、1 から「タイプ」の行数までの乱数を選択して、選択する行番号を選択します。このブロックは、フラグのために一度だけ実行されます。

最後の 2 つのブロックは、各行のレコード番号をチェックして、選択された行番号の配列にあるかどうかを確認し、ある場合は出力します。

于 2012-05-26T16:50:50.167 に答える
0

これはあなたのために働くかもしれません:

grep '^A' file2 | sort -R | head -$(grep -c '^A' file1) >file3
grep '^B' file2 | sort -R | head -$(grep -c '^B' file1) >>file3

注意これfile1はソートされていると仮定します。

于 2012-05-27T06:45:15.040 に答える