Bash 将列粘贴到循环中的现有文件

Bash 将列粘贴到循环中的现有文件,bash,shell,unix,paste,Bash,Shell,Unix,Paste,我在bash循环中使用paste命令向CSV文件添加新列。我想重新使用CSV文件。目前,我正在使用一个临时文件来完成此任务: while [ $i -le $max ] do # create text from grib2 wgrib2 -d 1.$(($i+1)) -no_header myGribFile.grb2 -text tmptxt.txt #paste to temporary file paste -d,

我在bash循环中使用paste命令向CSV文件添加新列。我想重新使用CSV文件。目前,我正在使用一个临时文件来完成此任务:

while [ $i -le $max ]
    do
        # create text from grib2
        wgrib2 -d 1.$(($i+1)) -no_header myGribFile.grb2 -text tmptxt.txt

        #paste to temporary file
        paste -d, existingfile.csv tmptxt.txt > tmpcsv.csv  

        #overwrite old csv with new csv
        mv tmpcsv.csv existingfile.csv

        ((i++))
    done
添加一些列后,复制速度变慢,因为文件越来越大(每个
tmptxt.txt
大约有2MB,增加到大约100MB)

tmptxt.txt
是一个普通的txt文件,每行有一列和一个值:

1
2
3
.
.
然后,现有的
文件.csv

1,1,x
2,2,y
3,3,z
.,.,.
.,.,.
有没有办法使用“粘贴”命令将列添加到现有文件中?或者还有别的办法吗


谢谢

假设程序输出的行数是恒定的,并且等于
existingfile.csv
中的行数(由于您使用的是
粘贴
,所以应该如此)

免责声明:我不确定这是否会加快速度(取决于io重定向
>
是否只写入文件一次)。无论如何,试试看,让我知道

所以基本的想法是

  • 循环完成后一次性追加输出(注意更改:wgrib现在打印到
    -
    ,即
    stdout

  • 使用awk将每个
    linenum
    行(
    linenum
    existingfile.csv
    中的行数)移动到第一行
    linenum
    的末尾

    保存到
    tempcv.csv
    (因为我找不到保存在同一文件中的方法)

  • 重命名为/overwrite
    existingfile.csv

  • 而[$i-le$max];做
    #从grib2创建文本
    wgrib2-d 1.$($i+1))-无标题myGribFile.grb2-文本-
    ((i++)
    完成>>现有文件.csv
    awk-v linenum=4'
    {array[FNR%linenum]=array[FNR%linenum],“$0}
    
    结束{for(i=1;i将操作拆分为2是否可行?一个步骤用于生成所有中间文件,另一个步骤用于生成所有最终输出文件。这样做的目的是避免反复读取和重写最终文件

    对脚本的更改如下所示:

    while [ $i -le $max ]
    do
        n=$(printf "%05d" $i)    # to preserve lexical order if $max > 9
        # create text from grib2
        wgrib2 -d 1.$(($i+1)) -no_header myGribFile.grb2 -text tmptxt$n.txt
        ((i++))
    done
    
    #make final file
    paste -d, existingfile.csv tmptxt[0-9]*.txt > tmpcsv.csv  
    
    #overwrite old csv with new csv
    mv tmpcsv.csv existingfile.csv
    

    另一种方法是收集要添加到中间块中的列(即,包含多个列的文件),以便粘贴之后可以运行得更快。这对您是否可行?如果您包含“创建tmptxt.txt的代码”。我们实际上可以帮助您。它将是:wgrib2-d1.$($i+1))-no_header myGribFile.grb2-text tmptxt。txt@JanitoVaqueiroFerreiraFilho听起来不错。你想的是像树一样的东西,对吗?我以前从来没有这样做过,我想了很多如果的和其他的。你知道一个简单的方法吗?老实说,没有=(.我会尝试使用嵌套的while循环,外部循环定义要连接的文件数量,内部循环实际将它们粘贴在一起。这种方法听起来不错,我还找到了一种不使用while循环(使用wgrib2)获取.csv的更快方法。)。但是awk还是减慢了速度,我在三种不同的方法中得到了大致相同的时间(都在24到27秒之间)。谢谢你的帮助!你是说即使使用
    wgrib2
    -
    粘贴
    -
    mv
    (不使用
    )你还是在同一时间得到了吗?是的,
    wgrib2-no_header myGribFile.grb2-text existingfile.csv
    (没有迭代)生成了一个类似于“混乱的前一条评论”的文件!我的意思是,我描述的方法,你的方法和另一个带有
    wgrib2
    -
    awk
    -
    -
    mv
    (没有
    while
    )很好,现在剧本只花了一半的时间。非常感谢你的帮助。@bennos:不客气。很高兴知道速度的提高。干杯。
    while [ $i -le $max ]
    do
        n=$(printf "%05d" $i)    # to preserve lexical order if $max > 9
        # create text from grib2
        wgrib2 -d 1.$(($i+1)) -no_header myGribFile.grb2 -text tmptxt$n.txt
        ((i++))
    done
    
    #make final file
    paste -d, existingfile.csv tmptxt[0-9]*.txt > tmpcsv.csv  
    
    #overwrite old csv with new csv
    mv tmpcsv.csv existingfile.csv