【问题标题】:Select random 3000 lines from a file with awk codes从带有 awk 代码的文件中随机选择 3000 行
【发布时间】:2011-11-22 19:32:57
【问题描述】:

我想从包含 8000 行的 sample.file 中随机选择 3000 行。 我将使用 awk 代码或从命令行执行此操作。我怎样才能做到这一点?

【问题讨论】:

    标签: random awk lines


    【解决方案1】:

    如果你有 gnu 排序,这很容易:

    sort -R FILE | head -n3000
    

    如果你有 gnu shuf,那就更简单了:

    shuf -n3000 FILE
    

    【讨论】:

    • 谢谢!很高兴知道 shuf 是专门为这个任务编写的。
    • 很好的答案。如果您需要从较短的列表/样本中选择大量随机选项,您可能需要-r 选项来启用替换。例如shuf -n5000 -r list-of-15-choices.txt
    【解决方案2】:
    awk 'BEGIN{srand();}
    {a[NR]=$0}
    END{for(i=1; i<=3000; i++){x=int(rand()*NR) + 1; print a[x];}}' yourFile
    

    【讨论】:

      【解决方案3】:

      根据 Glenn 的评论修复:

      awk 'BEGIN {
        a=8000; l=3000
        srand(); nr[x]
        while (length(nr) <= l) 
          nr[int(rand() * a) +  1]    
        }
      NR in nr
        ' infile 
      

      附:将数组传递给 length 内置函数是不可移植的,你已经被警告过 :)

      【讨论】:

      • +1,很好的答案。在您的 BEGIN 块中,填充 nr 数组后,您可能需要检查它的大小以确保您有 3000 个不同的数字。
      • @Glenn,非常正确 :) 谢谢,已修复。
      • 此答案与sort / shuf 答案的不同之处在于记录将始终按照它们在原始文件中出现的顺序出现。您可能关心也可能不关心。
      【解决方案4】:

      您可以使用awksorthead/tailsed 的组合来执行此操作,例如:

      pax$ seq 1 100 | awk '
      ...$    BEGIN {srand()}
      ...$          {print rand() " " $0}
      ...$ ' | sort | head -5 | sed 's/[^ ]* //'
      57
      25
      80
      51
      72
      

      如您所见,它从seq 1 100 中生成的一百行中随机选择五行。

      awk 技巧为文件中的每一行加上一个随机数和 "0.237788 " 格式的空格作为前缀,然后(显然)根据该随机数对其进行排序。

      然后您使用head(或tail,如果您没有head)来获取第一(或最后)N 行。

      最后,sed 将去掉随机数和空格以及每一行的开头。

      对于您的具体情况,您可以使用类似(单行):

      awk 'BEGIN {srand()} {print rand() " " $0}' file8000.txt
          | sort
          | tail -3000
          | sed 's/[^ ]* //'
          >file3000.txt
      

      【讨论】:

        【解决方案5】:

        我使用了这些命令,得到了我想要的:

        awk 'BEGIN {srand()} {print rand() " " $0}' examples/data_text.txt | sort -n | tail -n 80 | awk '{printf "%1d %s %s\n",$2, $3, $4}' > examples/crossval.txt
        

        实际上是从输入文件中随机选择 80 行。

        【讨论】:

          【解决方案6】:

          在 PowerShell 中:

          Get-Content myfile | Get-Random -Count 3000
          

          或更短:

          gc myfile | random -c 3000
          

          【讨论】:

            【解决方案7】:

            如果您只需要大约 3000 行,这是一个简单的方法:

            awk -v N=`cat FILE | wc -l` 'rand()<3000/N' FILE
            

            反引号 (`) 之间的部分表示文件中的行数。

            【讨论】:

              【解决方案8】:

              对于一个我不想洗牌的大文件,这运行得很好而且非常快:

              sed -u -n 'l1p;l2p; ... ;l1000p;l1000q'

              -u 选项减少了缓冲,l1, l2, ... l1000 是从 R 获得的随机和排序的行号(与 python 或 perl 一样好)。

              【讨论】:

                猜你喜欢
                • 2020-10-15
                • 2012-03-03
                • 1970-01-01
                • 1970-01-01
                • 2012-09-03
                • 1970-01-01
                • 2019-12-02
                • 2017-03-10
                相关资源
                最近更新 更多