将巨型文件拆分为特定数量的行

将巨型文件拆分为特定数量的行

我有一个 40 000 行长的 CSV。从第 x 行读取到第 y 行的最简单工具是什么?

我确信有更专业的方法可以做到这一点,但我只想要一个以以下形式工作的 bash 脚本

 readFile --from 10 --to 20

这样我就可以处理十行,然后再次调用它并再引入十行。我正在考虑只使用 AWK 脚本,但你能用catgreptail或 之类的东西更简单地做到这一点吗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 行为一组,有更好的方法。您可以head重复阅读 10 行。请注意使用chunk=$(…; 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

相关内容