次のデータのリストがあります。
12345
23456
67891
-20000
200
600
20
...
このデータセット(つまり、ファイル行)のサイズがN
。m
このデータファイルからランダムな線を描きたいです。したがって、出力は2つのファイルでなければなりません。 1つはこれらのm
データ行を含み、もう1つはそのようなN-m
データ行を含みます。
Linuxコマンドを使用してこれを行う方法はありますか?
答え1
これは最も効率的なアプローチではありませんが、次のように機能します。
shuf <file> > tmp
head -n $m tmp > out1
tail -n +$(( m + 1 )) tmp > out2
$m
行数を含みます。
答え2
このbash / awkスクリプトは行をランダムに選択し、2つの出力ファイルで元の順序を維持します。
awk -v m=4 -v N=$(wc -l <file) -v out1=/tmp/out1 -v out2=/tmp/out2 \
'BEGIN{ srand()
do{ lnb = 1 + int(rand()*N)
if ( !(lnb in R) ) {
R[lnb] = 1
ct++ }
} while (ct<m)
} { if (R[NR]==1) print > out1
else print > out2
}' file
cat /tmp/out1
echo ========
cat /tmp/out2
質問のデータに基づく出力です。
12345
23456
200
600
========
67891
-20000
20
答え3
Unixのすべてと同様に、Utility for ThatTMがあります。
今日のプログラム:split
split
ファイルをさまざまな方法、-b
バイト、-l
行、-n
出力ファイルの数に分割します。私たちはこのオプションを使います-l
。最初の行だけでなくランダムな行も選択したいので、ファイルをランダムに選択することから始めますm
。sort
これについて知りたい場合は、sort
私の答えを参照してください。ここ。
これで実際のコードです。本当に簡単です。
sort -R input_file | split -l $m output_prefix
これにより、2つのファイルが生成されます。 1つは行m
を含み、もう1つはおよびN-m
名前の行を含みます。必要なファイルが大きいことを確認してください。それ以外の場合は、同じ長さの複数のファイル(1つ)が生成されます。output_prefixaa
output_prefixab
m
m
N % m
正しい寸法を使用していることを確認するには、次のコードを使用してください。
m=10 # size you want one file to be
N=$(wc -l input_file)
m=$(( m > N/2 ? m : N - m ))
sort -R input_file | split -l $m output_prefix
編集:一部の実装にはフラグがsort
ないことがわかりました。-R
可能であればperl
交換できますperl -e 'use List::Util qw/shuffle/; print shuffle <>;'
。
答え4
仮定しm = 7
てN = 21
:
cp ints ints.bak
for i in {1..7}
do
rnd=$((RANDOM%(21-i)+1))
# echo $rnd;
sed -n "${rnd}{p,q}" 10k.dat >> mlines
sed -i "${rnd}d" ints
done
注:またはなどの変数を置き換える場合は、7
代わりに変数拡張を行わない - 表記法を使用する必要があります。$1
$m
seq
{from..to}
ファイルから1行ずつ削除するように機能しますが、ファイルが短くなるため、削除できる行番号も小さくなります。