#author("2020-07-30T00:53:25+09:00","default:nobuoki","nobuoki") #author("2020-09-29T01:29:00+09:00","default:nobuoki","nobuoki") * はじめに [#o8d027c7] 大量のテキストデータ(csvとかとか)をランダムに間引きたい時ってありますよね? - [[SUMO>https://www.eclipse.org/sumo/]]で死ぬほど車を走らせたがQGISで全部表示するの無理 - よく分かんないけど、N行毎に抽出するとデータが偏ってしまう何か * 答えの例 [#ia53bab6] 概ね 1/N にランダムに絞りたいときはこうするのが手っ取り早いです #prism(bash){{{ # int(rand N) == 0 のときだけ出力 cat "テキストファイル名" | perl -ne 'print if !int(rand N)' >"出力ファイル名" }}} 軽く試してみるとこんな感じです #prism(bash){{{ # 1から10,000までの連番を、概ね1/1,000 に間引く $ seq 10000 | perl -ne 'print if !int(rand 1000)' | nl 1 535 2 1211 3 1320 4 1806 5 3102 6 4458 7 5034 8 5256 9 5959 10 6208 11 6575 12 7511 13 9169 14 9940 }}} if の後で否定するくらいなら、unless の方が分かりやすいかもですね $ seq 10000 | perl -ne 'print unless int(rand 1000)' | nl * 別解の例 [#yb657c86] /dev/urandom を使って概ね 1/1000 に間引く例です - 入力ファイルの各行の頭に 000 - 999 の文字列を /dev/urandom を使ってランダムに割り振る - sed で先頭が 000 の行だけ抽出する #prism(bash){{{ tr -dc '0-9' </dev/urandom | fold -w3 | head -n $(wc -l <入力ファイル名) | paste -d, - 入力ファイル名 | sed -n '/^000/{s/^....//;p}' }}} 100,000 までのファイルを作り抽出した例です Macなので tr の前に LANG=C がついてたり、sed -> gsed とか変ですが気にしないで雰囲気だけ掴んで下さい #prism(bash){{{ $ seq 100000 >/tmp/dummy.txt $ LANG=C tr -dc '0-9' </dev/urandom | fold -w3 | head -n$(wc -l </tmp/dummy.txt) | paste -d, - /tmp/dummy.txt | gsed -n '/^000/{s/^....//;p}' | nl 1 928 (略) 88 98956 }}}