AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 521465
Accepted
Oli
Oli
Asked: 2014-09-09 02:39:49 +0800 CST2014-09-09 02:39:49 +0800 CST 2014-09-09 02:39:49 +0800 CST

如何将一个文件的内容重复n次?

  • 772

我正在尝试进行基准测试以比较两种不同的文件处理方式。我有少量输入数据,但为了获得良好的比较,我需要多次重复测试。

我不只是重复测试,而是想多次复制输入数据(例如 1000 次),这样一个 3 行的文件就变成了 3000 行,这样我就可以运行一个更令人满意的测试。

我通过文件名传递输入数据:

mycommand input-data.txt
command-line
  • 8 8 个回答
  • 21604 Views

8 个回答

  • Voted
  1. Best Answer
    cuonglm
    2014-09-09T03:36:58+08:002014-09-09T03:36:58+08:00

    你不需要input-duplicated.txt。

    尝试:

    mycommand <(perl -0777pe '$_=$_ x 1000' input-data.txt)
    

    解释

    • 0777: -0sets 设置输入记录分隔符(perl 特殊变量$/,默认为换行符)。将其设置为大于的值0400将导致 Perl 将整个输入文件拖入内存。
    • pe:-p意思是“在应用给它的脚本后打印每个输入行-e”。
    • $_=$_ x 1000:$_是当前输入行。因为我们一次读取整个文件,所以-0700这意味着整个文件。这x 1000将导致打印整个文件的 1000 份副本。
    • 22
  2. Oli
    2014-09-09T02:39:49+08:002014-09-09T02:39:49+08:00

    我原本以为我必须生成一个辅助文件,但我可以在 Bash 中循环原始文件并使用一些重定向使其显示为文件。

    可能有十几种不同的循环方式,但这里有四种:

    mycommand <( seq 1000 | xargs -i -- cat input-data.txt )
    mycommand <( for _ in {1..1000}; do cat input-data.txt; done )
    mycommand <((for _ in {1..1000}; do echo input-data.txt; done) | xargs cat )
    mycommand <(awk '{for(i=0; i<1000; i++)print}' input-data.txt)  #*
    

    第三种方法是根据下面 maru 的评论即兴创作的,并为 cat 构建了一个输入文件名的大列表。xargs将把它分成系统允许的尽可能多的参数。它比n只单独的猫快得多。

    这种awk方式(受terdon 的回答启发)可能是最优化的,但它一次复制每一行。这可能适合也可能不适合特定的应用程序,但它闪电般快速且高效。


    但这是即时生成的。Bash 输出可能比某些东西可以读取的要慢得多,因此您应该生成一个新文件进行测试。值得庆幸的是,这只是一个非常简单的扩展:

    (for _ in {1..1000}; do echo input-data.txt; done) | xargs cat > input-duplicated.txt
    mycommand input-duplicated.txt
    
    • 15
  3. evilsoup
    2014-09-09T05:07:29+08:002014-09-09T05:07:29+08:00

    我只会使用文本编辑器。

    vi input-data.txt
    gg (move cursor to the beginning of the file)
    yG (yank til the end of the file)
    G (move the cursor to the last line of the file)
    999p (paste the yanked text 999 times)
    :wq (save the file and exit)
    

    如果您绝对需要通过命令行执行此操作(这需要您vim安装,因为vi没有:normal命令),您可以使用:

    vim -es -u NONE "+normal ggyGG999p" +wq input-data.txt
    

    在这里,-es(或-e -s)让 vim 静默运行,所以它不应该接管你的终端窗口,并-u NONE阻止它查看你的 vimrc,这应该使它运行得比其他方式快一点(如果你使用,可能会快得多很多 vim 插件)。

    • 8
  4. terdon
    2014-09-09T05:37:21+08:002014-09-09T05:37:21+08:00

    这是一个awk解决方案:

    awk '{a[NR]=$0}END{for (i=0; i<1000; i++){for(k in a){print a[k]}}}' file 
    

    它基本上和@Gnuc 的 Perl 一样快(我都运行了 1000 次并得到了平均时间):

    $ for i in {1..1000}; do 
     (time awk '{a[NR]=$0}END{for (i=0;i<1000;i++){for(k in a){print a[k]}}}' file > a) 2>&1 | 
        grep -oP 'real.*?m\K[\d\.]+'; done | awk '{k+=$1}END{print k/1000}'; 
    0.00426
    
    $ for i in {1..1000}; do 
      (time perl -0777pe '$_=$_ x 1000' file > a ) 2>&1 | 
        grep -oP 'real.*?m\K[\d\.]+'; done | awk '{k+=$1}END{print k/1000}'; 
    0.004076
    
    • 7
  5. roeeb
    2016-03-11T10:19:36+08:002016-03-11T10:19:36+08:00

    这是一个简单的单行代码,不涉及脚本:

    mycommand <(cat `yes input-data.txt | head -1000 | paste -s`)
    

    解释

    • `yes input-data.txt | head -1000 | paste -s`input-data.txt生成由空格分隔 1000 次的文本
    • 然后将文本cat作为文件列表传递给
    • 5
  6. Sergiy Kolodyazhnyy
    2017-01-08T01:40:32+08:002017-01-08T01:40:32+08:00

    在处理完全不同的脚本时,我了解到,对于 2900 万行文本,按字节使用seek()和操作数据通常比逐行更快。下面的脚本中应用了相同的想法:我们打开文件,而不是循环打开和关闭文件(这可能会增加开销,即使不重要),我们保持文件打开并返回到开头。

    #!/usr/bin/env python3
    from __future__ import print_function
    import sys,os
    
    def error_out(string):
        sys.stderr.write(string+"\n")
        sys.exit(1)
    
    def read_bytewise(fp):
        data = fp.read(1024)
        print(data.decode(),end="",flush=True)
        while data:
            data = fp.read(1024)
            print(data.decode(),end="",flush=True)
        #fp.seek(0,1)
    
    def main():
        howmany = int(sys.argv[1]) + 1
        if not os.path.isfile(sys.argv[2]):
           error_out("Needs a valid file") 
    
        fp = open(sys.argv[2],'rb')
        for i in range(1,howmany):
            #print(i)
            fp.seek(0)
            read_bytewise(fp)
        fp.close()
    
    if __name__ == '__main__': main()
    

    脚本本身的使用非常简单:

    ./repeat_text.py <INT> <TEXT.txt>
    

    对于 3 行文本文件和 1000 次迭代,一切正常,大约 0.1 秒:

    $ /usr/bin/time ./repeat_text.py 1000 input.txt  > /dev/null                                                             
    0.10user 0.00system 0:00.23elapsed 45%CPU (0avgtext+0avgdata 9172maxresident)k
    0inputs+0outputs (0major+1033minor)pagefaults 0swaps
    

    脚本本身不是最优雅的,可能可以缩短,但可以完成工作。当然,我在这里和那里添加了一些额外的位,比如error_out()功能,这不是必需的——这只是一个小的用户友好的触摸。

    • 2
  7. user379914
    2015-07-30T22:11:17+08:002015-07-30T22:11:17+08:00

    我们可以解决这个问题,不需要额外的文件,也不需要特殊的程序,纯 Bash(好吧,cat 是一个标准命令)。

    基于 bash 中 printf 的一个特性,我们可以生成一个重复的字符串):

    printf "test.file.txt %.0s\n" {1..1000}
    

    然后,我们可以发送这样的 1000 个文件名列表(重复)并调用 cat:

    printf "test.file.txt %.0s" {1..1000} | xargs cat 
    

    最后,我们可以将输出提供给要执行的命令:

    mycommand "$( printf "%.0sinput.txt\n" {1..1000} | xargs cat )"
    

    或者,如果命令需要接收标准输入中的输入:

    mycommand < <( printf "%.0sinput.txt\n" {1..1000} | xargs cat )
    

    是的,双 < 是必需的。

    • 1
  8. SmallChess
    2016-12-12T19:47:38+08:002016-12-12T19:47:38+08:00

    我将使用 Unix for 循环生成一个新文件:

    content=$(cat Alex.pgn); for i in {1..900000}; do echo "$content" >> new_file; done 
    
    • 0

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve