从数据文件中随机绘制一定数量的线

从数据文件中随机绘制一定数量的线

我有一个数据列表,例如

12345
23456
67891
-20000
200
600
20
...

假设该数据集的大小(即文件行)为N。我想m从这个数据文件中随机绘制线条。因此,输出应该是两个文件,一个是包含这些m行数据的文件,另一个是包含这些N-m行数据的文件。

有没有办法使用 Linux 命令来做到这一点?

答案1

这可能不是最有效的方法,但它有效:

shuf <file> > tmp
head -n $m tmp > out1
tail -n +$(( m + 1 )) tmp > out2

$m行数。

答案2

此 bash/awk 脚本随机选择行,并在两个输出文件中维护原始序列。

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 的所有事物一样,There's a Utility for That TM

今日程序:split
split将以多种不同的方式分割文件,-b字节、-l行、-n输出文件的数量。我们将使用该-l选项。由于您想选择随机行而不仅仅是第一行m,因此我们sort首先随机选择文件。如果您想了解相关内容sort,请参阅我的回答这里

现在,实际的代码。这真的很简单:

sort -R input_file | split -l $m output_prefix

这将生成两个文件,一个包含m行,另一个包含N-m行,名为output_prefixaaoutput_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 = 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}

它的工作原理是从文件中逐行删除,文件变得越来越短,因此可以删除的行号也必须变得越来越小。

这不应该用于较长的文件和很多行,因为对于每个数字,平均而言,第一个需要读取半个文件,第二个需要读取整个文件sed代码。

相关内容