2つの並列テキストファイルをシャッフルする


9

約50 milの単語を含む2つの文に揃えられた平行コーパス(テキストファイル)があります。(Europarlコーパスから->法的文書の並行翻訳)。2つのファイルの行をシャッフルしたいのですが、どちらも同じ方法です。私は、gshuf(私はMacを使用しています)を使用して、1つの一意のランダムソースを使用してそれにアプローチしたいと思いました。

gshuf --random-source /path/to/some/random/data file1
gshuf --random-source /path/to/some/random/data file2

しかしend of file、ランダムシードには、ソートするファイルに含まれるすべての単語を含める必要があるため、エラーメッセージが表示されました。本当?はいの場合、自分のニーズに合ったランダムシードをどのように作成すればよいですか?いいえの場合、他にどのようにファイルを並行してランダム化できますか?それらを一緒に貼り付け、ランダム化してから再び分割することを考えました。ただし、ファイルで発生しない区切り文字を最初に見つける必要があるため、これは醜いようです。


1
random_fileに十分なバイトが含まれていないため、このエラーが発生しました...を参照してくださいrandom sources。に関してpasteは、ファイルで発生する可能性の低いいくつかの低ASCII文字(\x02\x03...など)を区切り文字として使用できます。
don_crissti

了解しました。ランダム化したいものは何でも、/ dev / urandomを使用すれば、いいですよね。貼り付け区切り文字は良いヒントです、ありがとう!
conipo

回答:


10

よりエレガントな方法があるかどうかはわかりませんが、これは私にとってはうまくいきます:

mkfifo onerandom tworandom threerandom
tee onerandom tworandom threerandom < /dev/urandom > /dev/null &
shuf --random-source=onerandom onefile > onefile.shuf &
shuf --random-source=tworandom twofile > twofile.shuf &
shuf --random-source=threerandom threefile > threefile.shuf &
wait

結果:

$ head -n 3 *.shuf
==> onefile.shuf <==
24532 one
47259 one
58678 one

==> threefile.shuf <==
24532 three
47259 three
58678 three

==> twofile.shuf <==
24532 two
47259 two
58678 two

ただし、ファイルの行数はまったく同じでなければなりません。


GNU Coreutilsのドキュメントにはopenssl、シードされたランダムジェネレーターとして繰り返しランダム性を使用するための優れたソリューションも用意されています。

https://www.gnu.org/software/coreutils/manual/html_node/Random-sources.html#Random-sources

get_seeded_random()
{
  seed="$1"
  openssl enc -aes-256-ctr -pass pass:"$seed" -nosalt \
    </dev/zero 2>/dev/null
}

shuf -i1-100 --random-source=<(get_seeded_random 42)

ただし、誰かが「自分の」ランダムな結果も再現できるようにしたくない場合を除き、「42」よりも優れたシードの使用を検討してください。


これは魅力のように機能します。あなたが取った手順を説明していただけませんか?teeコマンドは、同じ乱数が3つのパイプすべてに確実に格納されるようにしますよね?なぜ/ dev / nullにも出力する必要があるのですか?そして、それは十分なバイトがあることとend of fileエラーが発生しないことを自動的に保証されていますか?
conipo

/dev/nullためであるteeとも印刷しますstdout> threerandom代わりに使用できますが、スクリプトを作成するのは困難です。名前付きパイプは、必要なだけのランダムデータを生成するため、事前に必要なデータ量を知る必要はありません。
frostschutz

それでは、3つすべてのシャッフルのランダムソースとして次々に使用する1つのパイプにできないのはなぜですか。
conipo

2
1つのパイプから同じデータを3回読み取ることはできません。どうにかして多重化する必要があり、それが何をするのかtee...
frostschutz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.