Red Hat Linuxの標準ツールを使用してファイルの行をランダム化するにはどうすればよいですか?
shuf
コマンドを持っていないので、同じタスクを実行するa perl
またはawk
one-linerのようなものを探しています。
Red Hat Linuxの標準ツールを使用してファイルの行をランダム化するにはどうすればよいですか?
shuf
コマンドを持っていないので、同じタスクを実行するa perl
またはawk
one-linerのようなものを探しています。
回答:
そして、Perlのワンライナーが手に入ります!
perl -MList::Util -e 'print List::Util::shuffle <>'
モジュールを使用していますが、モジュールはPerlコード配布の一部です。それでも十分でない場合は、自分でロールすることを検討してください。
これを-i
フラグ( "edit-in-place")と共に使用して、ファイルを編集してみました。ドキュメントは、それが動作するはずであると示唆していますが、動作しません。シャッフルされたファイルは引き続きstdoutに表示されますが、今回は元のファイルが削除されます。使用しないことをお勧めします。
シェルスクリプトを考えてみましょう:
#!/bin/sh
if [[ $# -eq 0 ]]
then
echo "Usage: $0 [file ...]"
exit 1
fi
for i in "$@"
do
perl -MList::Util -e 'print List::Util::shuffle <>' $i > $i.new
if [[ `wc -c $i` -eq `wc -c $i.new` ]]
then
mv $i.new $i
else
echo "Error for file $i!"
fi
done
テストされていませんが、うまくいけばうまくいきます。
ruby -e 'puts STDIN.readlines.shuffle'
。速度が同等かどうかを確認するには、大きな入力をテストする必要があります。(OS Xでも動作します)
shuf
すべてをメモリにロードするため、本当に巨大なファイル(私の場合は約300GB tsv)では機能しません。このperlスクリプトは私のものでも失敗しましたが、以外のエラーはありませんでしたKilled
。Perlソリューションがすべてをメモリにロードしているのか、それとも私が遭遇している他の問題があるのか?
ええと、忘れないで
sort --random-sort
brew install coreutils
すべてのutilsのはとてもAGが付いていますgsort --random-sort
かgshuf
期待通りに動作します
gsort
おり、gshuf
インストール時にもインストールしていたport install coreutils
shuf
代わりに(Linux上で)使用することを検討してください。
shuf
最良の方法です。
sort -R
痛いほど遅いです。5GBのファイルをソートしてみました。2.5時間後にあきらめました。次にshuf
、1分で並べ替えました。
shuf
すべてをメモリにロードします。
seq -f 'line %.0f' 1000000
と、割り当てたメモリの量に関係なく、処理に同じ長い時間がかかりました(の場合よりはるかに長いshuf
)。
cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
ファイルを読み取り、すべての行にランダムな番号を付加し、それらのランダムなプレフィックスでファイルをソートし、その後プレフィックスをカットします。セミモダンシェルで機能するワンライナー。
編集:リチャードハンセンの発言を組み込んだ。
$RANDOM
)の場合は+1 、データをブッチャーする場合は-1。で置換while read f
するwhile IFS= read -r f
と、read
先頭と末尾の空白(この回答を参照)が削除されなくなり、バックスラッシュが処理されなくなります。固定長のランダム文字列を使用すると、cut
先頭の空白が削除されなくなります。結果: cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Pythonのワンライナー:
python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile
そして、ランダムな1行だけを印刷する場合:
python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile
しかし、pythonの欠点については、この投稿を参照してくださいrandom.shuffle()
。多くの(2080を超える)要素ではうまく機能しません。
ジムの答えに関連して:
私~/.bashrc
には以下が含まれます:
unsort ()
{
LC_ALL=C sort -R "$@"
}
GNU coreutilsのsort -R
= --random-sort
を使用すると、各行のランダムハッシュが生成され、それによってソートされます。ランダム化されたハッシュは、一部の古い(バグのある)バージョンの一部のロケールでは実際には使用されないため、通常のソートされた出力が返されるため、を設定しましたLC_ALL=C
。
クリスの答えに関連して:
perl -MList::Util=shuffle -e'print shuffle<>'
少し短いワンライナーです。(-Mmodule=a,b,c
はの省略形です-e 'use module qw(a b c);'
。)
シンプルに指定-i
してもインプレースのシャッフルが機能しない理由は、Perlはprint
ファイルが読み込まれている同じループで発生することを想定しており、print shuffle <>
すべての入力ファイルが読み込まれて閉じられるまで出力されないためです。
より短い回避策として、
perl -MList::Util=shuffle -i -ne'BEGIN{undef$/}print shuffle split/^/m'
ファイルをその場でシャッフルします。(-n
「while (<>) {...}
ループでコードをラップしますBEGIN{undef$/}
。Perlを行単位ではなくファイル単位で操作できるようにします。これは、行でsplit/^/m
は$_=<>
なくファイル全体で暗黙的に行われているために必要です。)
OSXでは、http://ftp.gnu.org/gnu/coreutils/などから最新のものを取得します
./configure make sudo make install
... / usr / local / bin / sort --random-sortが表示されます
/ usr / bin / sortを台無しにすることなく
または、MacPortsから入手します。
$ sudo port install coreutils
および/または
$ /opt/local//libexec/gnubin/sort --random-sort