【问题标题】:pick a random line from a very big file, from command line从一个非常大的文件中选择一个随机行,从命令行
【发布时间】:2014-07-23 02:47:05
【问题描述】:

假设您有一个非常大的文件,并且通过所有行或减慢速度会很昂贵。

你会如何随机选择一行(最好是从命令行或 python)?

【问题讨论】:

  • 在不提前知道文件中有多少行以及每行从哪里开始的情况下,不可能从文件中随机选择一行。否则,您必须阅读整个文件。请参阅stackoverflow.com/questions/232237/… 获取灵感。
  • 您可以使用 wcsed .. 看看 jim 的回答
  • 整个文件的行长是否被限制为常数?
  • @moooeeeep,如果是这样,我们的想法是将文件大小与平均记录长度相除,以估计文件中的行数?
  • 也看看这个问题,了解一些不诉诸于处理整个文件至少一次的建议:stackoverflow.com/q/13478232/1025391

标签: python linux file random io


【解决方案1】:

您可以从命令行尝试此操作 - 不确定是否完全随机,但至少是一个开始。

$ lines=$(wc -l file | awk '{ print $1 }'); sed -n "$((RANDOM%lines+1))p" file  

这样工作:

  • 首先,它设置一个包含文件行数的变量。

    lines=$(wc -l file | awk '{ print $1 }')
    
  • 稍后,它会在该范围内打印一条随机线:

    sed -n "$((RANDOM%lines+1))p" file
    

正如 Mark Ransom 所指出的,上述解决方案会读取整个文件。我找到了一种选择随机行的方法,而无需(必须)读取整个文件,而只是其中的一部分。使用(我认为)相同的算法,这里是 Perl 和 Python 解决方案的链接:

  • Perl:How do I pick a random line from a file?

    perl -e 'srand;' \
         -e 'rand($.) < 1 && ($it = $_) while <>;' \
         -e 'print $it' FILE
    
  • Python:Retrieving a Line at Random from a File of Unknown Size

    import random
    
    def randomLine(file_object):
        "Retrieve a random line from a file, reading through the file once"
        lineNum = 0
        selected_line = ''
    
        while 1:
            aLine = file_object.readline(  )
            if not aLine: break
            lineNum = lineNum + 1
            # How likely is it that this is the last line of the file?
            if random.uniform(0,lineNum)<1:
                selected_line = aLine
        file_object.close(  )
        return selected_line
    

【讨论】:

  • wc 将读取整个文件,sed 将读取到选定的行。这在技术上回答了这个问题,但违反了规定的限制。
【解决方案2】:

如果你想用 python 来做。给你。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import os
import random

def test():
    filename = 'yourfile'
    info = os.popen('wc -l filename').readlines()
    line_number = info[0].split()[0]

    r = random.randrange(line_number)
    cmd = 'sed -n "%dp" %s' % (r, filename)
    info = os.popen(cmd).readlines()

    print info



if __name__ =='__main__':

    test()

【讨论】:

    【解决方案3】:

    也许你可以使用linecache,

    import linecache
    linecache.getline(file_path, line_no)
    

    【讨论】:

      猜你喜欢
      • 2019-02-09
      • 1970-01-01
      • 1970-01-01
      • 2020-09-23
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多