簡體   English   中英

Bash:從 CSV 中一次循環讀取 N 行

[英]Bash: Loop Read N lines at time from CSV

我有一個 100000 個 ID 的 csv 文件

wef7efwe1fwe8
wef7efwe1fwe3
ewefwefwfwgrwergrgr

正在使用 jq 轉換為 json 對象

output=$(jq -Rsn '
{"id":
  [inputs
    | . / "\n"
    | (.[] | select(length > 0) | . / ";") as $input
    | $input[0]]}
' <$FILE)

輸出

{
  "id": [
         "wef7efwe1fwe8",
         "wef7efwe1fwe3",
         ....
   ]
}

目前,我需要手動將文件拆分為更小的 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 程序之外指定批大小可能是有意義的。 這可以通過多種方式完成,例如通過沿以下方式調用 jq :

jq --argjson n 10000 ....

當然,在 jq 程序中使用$n而不是 10000。

為什么是“def b:”?

為了效率。 jq 的 TCO(尾遞歸優化)僅適用於 arity-0 過濾器。

注意 -s

在最初發布的 Q 中,命令行選項 -sn 與inputs結合使用。 使用-s與inputs失敗的整個目的inputs ,這是為了使其能夠在一個面向流的方式處理輸入(一次輸入或一個JSON實體即,一個線)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM