Linux Bash:循环从CSV一次读取N行

Linux Bash:循环从CSV一次读取N行,linux,bash,shell,unix,jq,Linux,Bash,Shell,Unix,Jq,我有一个100000 ID的csv文件 wef7efwe1fwe8 wef7efwe1fwe3 ewefwefwfwgrwergrgr 正在使用jq转换为json对象的 output=$(jq -Rsn ' {"id": [inputs | . / "\n" | (.[] | select(length > 0) | . / ";") as $input | $input[0]]} ' <$FI

我有一个100000 ID的csv文件

wef7efwe1fwe8
wef7efwe1fwe3
ewefwefwfwgrwergrgr
正在使用jq转换为json对象的

output=$(jq -Rsn '
{"id":
  [inputs
    | . / "\n"
    | (.[] | select(length > 0) | . / ";") as $input
    | $input[0]]}
' <$FILE)
目前,我需要手动将该文件拆分为更小的10000行文件。。。因为API调用有一个限制


我想一种方法来自动循环通过大文件。。。并且一次只使用10000行作为$FILE。。。直到列表结束。

我将使用
split
命令并围绕它编写一个小shell脚本:

#!/bin/bash
input_file=ids.txt
temp_dir=splits
api_limit=10000

# Make sure that there are no leftovers from previous runs
rm -rf "${temp_dir}"
# Create temporary folder for splitting the file
mkdir "${temp_dir}"
# Split the input file based on the api limit
split --lines "${api_limit}" "${input_file}" "${temp_dir}/"

# Iterate through splits and make an api call per split
for split in "${temp_dir}"/* ; do
    jq -Rsn '
        {"id":
          [inputs
            | . / "\n"
            | (.[] | select(length > 0) | . / ";") as $input
            | $input[0]]
        }' "${split}" > api_payload.json

    # now do something ...
    # curl -dapi_payload.json http://...

    rm -f api_payload.json
done

# Clean up
rm -rf "${temp_dir}"

这里有一个简单而高效的解决方案,其核心就是使用jq。它利用了-c命令行选项。我使用了
xargs printf…
进行了说明,主要是为了说明设置shell管道是多么容易

< data.txt jq -Rnc '
  def batch($n; stream):
    def b: [limit($n; stream)]
    | select(length > 0)
    | (., b);
    b;

  {id: batch(10000; inputs | select(length>0) | (. / ";")[0])}
' | xargs printf "%s\n"
当然,在jq程序中使用
$n
而不是10000

为什么是“DEFB:”? 为了效率。jq的TCO(尾部递归优化)只适用于arity-0过滤器

关于-s的说明
在最初发布的Q中,命令行选项-sn与
输入一起使用。将-s与
输入一起使用
违背了
输入
的全部目的,即以面向流的方式处理输入(即一次一行输入或一个JSON实体)。

提示:
拆分(1)
请发布足够的代码,以便其他用户可以运行。将-sn与
输入一起使用是一种反模式!好的一点,我从OP中得到了这一点,以关注主要问题(不要因为缺少示例数据而冒险出错)。我附带了这个
jq
命令
jq-sR'{id:(split(“\n”)[:-1]| map(split(“;”[0]))}'
,稍微简单一点,但仍然需要为您的方法提供整个文件:(…+1)
< data.txt jq -Rnc '
  def batch($n; stream):
    def b: [limit($n; stream)]
    | select(length > 0)
    | (., b);
    b;

  {id: batch(10000; inputs | select(length>0) | (. / ";")[0])}
' | xargs printf "%s\n"
jq --argjson n 10000 ....