web-dev-qa-db-ja.com

2つのパラレルテキストファイルをシャッフルします

私は約5000万語の2つの文に揃えられた並列コーパス(テキストファイル)を持っています。 (Europarlコーパスから->法的文書の並行翻訳)。 2つのファイルの行をシャッフルしたいのですが、どちらも同じ方法です。私は1つのユニークなランダムソースを使用してgshuf(私はMacを使用しています)を使用してそれにアプローチしたかったのです。

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

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

9
conipo

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

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」よりも優れたシードを使用することを検討してください。

10
frostschutz