Dividir arquivos gigantes em um número específico de linhas

2

Eu tenho um CSV com 40 000 linhas. Qual é a ferramenta mais simples para ler da linha x à linha y?

Tenho certeza de que existem maneiras mais profissionais de fazer isso, mas gostaria apenas de um script bash que funcione na forma de

 readFile --from 10 --to 20

para que eu possa processar dez linhas, ligue novamente e traga mais dez linhas. Eu estava pensando em usar apenas um script AWK, mas você pode fazer isso ainda mais simplesmente com algo como cat , grep , tail ou head ?

    
por Prospero 02.09.2011 / 14:05

2 respostas

2
#!/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
    
por 02.09.2011 / 14:37
2

A extração das linhas 10 a 20 de um arquivo é uma combinação simples de head e tail :

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

Este comando pula 10 linhas e processa as próximas 10. Se você quiser processar todas as linhas no arquivo em seqüência, mas por grupos de 10, existem maneiras melhores. Você pode ler 10 linhas com head repetidamente. Observe o uso de chunk=$(…; echo a) seguido por remover o a , para contornar a supressão de novas linhas finais nas substituições de comandos. Essa abordagem tem a vantagem de funcionar mesmo se a entrada for um pipe (que você não pode retroceder) e também é mais rápido para um arquivo regular. Aviso, código não testado, digitado diretamente no navegador.

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

Alternativamente, você pode fazer o awk fazer o trabalho. Mais uma vez, não testado.

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

Tags