データファイルから任意の数の線を描画する

データファイルから任意の数の線を描画する

次のデータのリストがあります。

12345
23456
67891
-20000
200
600
20
...

このデータセット(つまり、ファイル行)のサイズがNmこのデータファイルからランダムな線を描きたいです。したがって、出力は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。最初の行だけでなくランダムな行も選択したいので、ファイルをランダムに選択することから始めますmsortこれについて知りたい場合は、sort私の答えを参照してください。ここ

これで実際のコードです。本当に簡単です。

sort -R input_file | split -l $m output_prefix

これにより、2つのファイルが生成されます。 1つは行mを含み、もう1つはおよびN-m名前の行を含みます。必要なファイルが大きいことを確認してください。それ以外の場合は、同じ長さの複数のファイル(1つ)が生成されます。output_prefixaaoutput_prefixabmmN % 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 = 7N = 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$mseq{from..to}

ファイルから1行ずつ削除するように機能しますが、ファイルが短くなるため、削除できる行番号も小さくなります。

長いファイルや多くの行には使用しないでください。各数値について、平均して最初のファイルはファイルの半分を読み、2番目のファイルはファイル全体を読み取る必要があるためです。sedパスワード。

関連情報