如何将较大的CSV分成较小批量的CSV?

时间:2018-02-23 21:02:30

标签: bash csv

我有50k CSV字符串(它是一个带有50k值的单个字符串),格式23445,23446,24567,...等等。我想创建一个包装脚本,将其分成500个批次并将其传递给脚本接受它作为输入。

input.csv(50k逗号分隔值)

脚本(500个批次),节流60秒,再获取500个数据。

#!/bin/bash
input.csv | sed -n 1'p' | tr ',' '\n' | while read word; do
script_accpts_batch_of_500=$word
done

3 个答案:

答案 0 :(得分:1)

您可以将不同的命令与

组合使用
tr ',' '\n' < input.csv | paste -d, $(yes -- "- " | head -500)

您也可以使用一个命令:

awk 'BEGIN {RS=","} {if (NR%500==0) print $0  ; else  printf $0 RS; }' input.csv

答案 1 :(得分:1)

另一个awk解决方案可以

$ awk -v RS=, '{ORS=NR%500?RS:"\n"}1' file

答案 2 :(得分:1)

我不太了解您将启动此类设置的设置,这里是一个更独立的脚本。使用awk(splitcsv)的shell函数是将CSV格式的非常长的行拆分成CSV格式的较小行的一种方法,由一些函数包围以生成测试输入和模拟处理。

awk的这种使用仅留下记录分隔符(RS)值,而是通过awk&#39; -F选项设置FS。 &#34;长&#34;因此,如果splitcsv出现了许多,在当前长线耗尽之前发出尽可能多的500场线,然后发出一条短线 - 少于500个场,则CSV输入线全部被处理在处理下一条长线之前。

但是你只要求处理一条长线,所以我要停在这里。

#!/usr/bin/env bash

stepdown_csv() {
  local n=500
  [[ $# -eq 1 ]] && n="$1"

  generate50000 |
  splitcsv "$n" |
  while IFS= read -r line; do
    process_csv_line "$line"
  done
}

process_csv_line() {
  local unsep=$(sed 's/,/ /g' <<< "$1")

  if [[ "$unsep" != '' ]]; then
    set $unsep
    echo "Got a CSV line with $# fields"
    # sleep 60
  fi
}

splitcsv() {
  awk -F , -v flds="$1" '{
    for (n=1; n<=NF; n++) {
      printf "%s%s", $n, n % flds == 0 || n == NF ? "\n" : ","
    }
  }'
}

generate50000() {
  for n in {1..50000}; do
    echo -n $RANDOM
    if [[ n -lt 50000 ]]; then
      echo -n ,
    else
      echo
    fi
  done
}

stepdown_csv "$@"