6

我在 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都有大约 2 MB,增加到大约 100 MB)。

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

1
2
3
.
.

existingfile.csv那么将是

1,1,x
2,2,y
3,3,z
.,.,.
.,.,.

有没有办法使用粘贴命令将列添加到现有文件?或者还有其他方法吗?

谢谢

4

2 回答 2

6

将操作拆分为 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
于 2012-10-16T16:29:21.500 回答
0

假设程序输出的行数是恒定的并且等于行数existingfile.csv(应该是这种情况,因为您正在使用paste

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

所以基本思想是

  1. 循环完成后一次性追加输出(注意更改:wgrib 现在打印到-which is stdout

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

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

  3. 重命名为/覆盖existingfile.csv

.

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

  ((i++))
done >> existingfile.csv

awk -v linenum=4 '
  { array[FNR%linenum]=array[FNR%linenum]","$0 } 
  END { for(i=1;i<linenum;i++) print array[i%linenum] }
' existingfile.csv > tempcsv.csv

mv tempcsv.csv existingfile.csv

如果这是我想象的(内部)工作方式,那么您应该有 2 次写入existingfile.csv而不是$max写入次数。所以希望这会加快速度。

于 2012-10-16T14:56:29.067 回答