拆分CSV并保持标头没有中间文件

时间:2014-11-03 05:05:09

标签: bash csv curl cat tail

我正在尝试将十几个100MB + csv文件拆分为可管理的较小文件以用于卷曲帖子。

我已经设法做了但是有很多临时文件和IO。这是永恒的。

我希望有人能告诉我一种更有效地做到这一点的方法;最好是几乎没有磁盘     #!/ bin / sh的

for csv in $(ls *.csv); do
    tail -n +2 $csv | split -a 5 -l - $RANDOM.split.
done

# chose a file randomly to fetch the header from   

header=$(ls *.csv |sort -R |tail -1 | cut -d',' -f1)

mkdir split

for x in $(/usr/bin/find . -maxdepth 1 -type f -name '*.split.*'); do
    echo Processing $x
    cat header $x >> split/$x
    rm -f $x
done

上述脚本可能无法完全发挥作用。我基本上通过这些命令的组合来完成它。

我决定在上传失败的情况下完全将curl POST作为另一个步骤;如果全部发布,我不想丢失数据。但是,如果,例如,从卷曲的错误,数据可以放入一个重做文件夹然后可以工作。

#!/bin/sh

# working on a progress indicator as a percentage. Never finished.
count=$(ls -1 | wc -l 2> /dev/null | cut -d' ' -f1)

for file in $(/usr/bin/find . -maxdepth 1 -type f); do
    echo Processing $file
    curl -XPOST --data-binary @$file -H "Content-Type: text/cms+csv" $1
done

编辑1 - 为什么RANDOM?因为split会在分割下一个文件时产生与第一个文件完全相同的文件。所以... aa ab ac ...将为每个文件生成。我需要确保split生成的每个文件对于整个运行都是唯一的

1 个答案:

答案 0 :(得分:0)

不太确定你想要完成什么,但在我看来,你正在逐行处理。因此,如果序列化所有csv文件和行,则可以在没有磁盘I / O的情况下执行此操作。然而,根据您的描述,我无法判断此脚本是运行多个实例还是仅运行一个实例(多个进程或一个进程)。因此,我可以尽我所能模仿您的脚本,以达到尽可能相似的结果,但要解决磁盘I / O问题。下面提供了代码,但请更正脚本错误,因为我无法运行/调试/验证它:

for csv in $(ls *.csv | sort -R); do
    # first read line skip the first line, since I see your tail -n +2 command.
    (read line;
     count=0;
     while read line; do
         Processing $line;
         count=$(($count + 1));
         echo $csv.$count >> split/$count;
     done
    ) < $csv
done

您的处理&#39;代码现在应该从详细的行而不是文件进行处理。也许是一个管道并让你的Processing在STDIN上处理就可以了:

echo $line | Processing

你的卷曲可以采用类似的方式,从STDIN进行处理,将@$file替换为-,然后你可以打印你想要发送的卷发,然后将其管道卷曲,类似于:

ProcessingAndPrint | curl -XPOST --data-binary - -H "Content-Type: text/cms+csv" $1