大容量ファイルを特定の行数に分割する

大容量ファイルを特定の行数に分割する

行長が40,000個のCSVがあります。 x行からy行まで読む最も簡単なツールは何ですか?

これを行うためのより専門的な方法があると確信していますが、次の形式で動作するbashスクリプトが必要です。

 readFile --from 10 --to 20

これにより、10行を処理してからもう一度呼び出して10行をさらにインポートできます。 AWKスクリプトだけを使用しようとしていますが、catそれとgreptailたようなものを使用してより簡単に実行できますかhead

答え1

#!/bin/sh

while getopts "f:t:" option; do
  case "$option" in 
    f) from=$OPTARG ;;
    t) to=$OPTARG ;;
  esac
done
if [ -z "$from" ] || [ -z "$to" ]; then
  echo "must give both -f and -t" >&2
  exit 1
fi

awk -v "from=$from" -v "to=$to" 'from <= NR && NR <= to' filename

# or:
sed -n "$from,$to p; $to q" filename

# or:    
i=0
while read line; do
  i=$(( i + 1 ))
  if [ $i -ge $from ] && [ $i -le $to ]; then
    printf "%s\n" "$line"
  fi
  [ $i -eq $to ] && break
done < filename

答え2

ファイルの10〜20行を抽出するのは、head次の簡単な組み合わせですtail

tail -n +11 | head -n 10 | mycommand

このコマンドは10行をスキップし、次の10行を処理します。ファイル内のすべての行を順番に処理しますが、10個ずつグループとして処理したい場合は、より良い方法があります。 10行を繰り返し読み取ることができますheadchunk=$(…; echo a)末尾の削除は、コマンドa置換で最後の改行文字を抑制する問題を解決するために使用されます。このアプローチの利点は、入力がパイプされている場合でも動作し(巻き戻すことはできません)、通常のファイルの場合でも高速です。警告、テストされていないコードがブラウザに直接入力されました。

while chunk=$(head -n 10; echo a); chunk=${chunk#a}; [ -n "$chunk" ]; do
  printf %s "$chunk" | mycommand
done <filename

あるいは、awkにアクションを実行させることもできます。繰り返しますが、テストされていません。

awk '
    {chunk = chunk $0 RS}
    NR % 10 {print chunk | "mycommand"; close("mycommand"); chunk="" }
    END {if (chunk != "") {print chunk | "mycommand"; close("mycommand"); chunk="" }}
' <filename

関連情報