Eu tenho um arquivo CSV bastante considerável (75 MB). Estou apenas tentando produzir um gráfico, então realmente não preciso de todos os dados.
Reescrita: eu gostaria de excluir n linhas, manter uma linha, excluir n linhas e assim por diante.
Portanto, se o arquivo estiver assim:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
e n = 2, a saída seria:
Line 3
Line 6
Parece que sed
é capaz de fazer isso, mas não consegui descobrir como. Um comando bash seria ideal, mas estou aberto a qualquer solução.
Respostas:
NR
A variável (número de registros) é o número de linhas de registros porque o comportamento padrão é a nova linha deRS
(separador de registros). padrão e ação são opcionais no formato padrão do awk'pattern {actions}'
. quando damos apenas parte do padrão,awk
grava todos os campos$0
para astrue
condições do nosso padrão .fonte
awk 'NR == 1 || NR % 3 == 0'
awk 'NR == 1 || NR % 2 == 0' myfile.txt | wc -l
resultado de um número ímpar, enquanto o arquivo original tinha um número par de linhas. A resposta do @kev funciona melhor no meu caso de teste.sed
também pode fazer isso:man sed
explica~
como:fonte
1p
imprime a primeira linha,0~3p
imprime todas as terceiras linhas iniciando na linha 3 (1p
portanto, é necessário imprimir a linha 1). Mas note que o0~3
não é padrão, mas uma extensão GNU sed.sed -n '1p;0~10p' '.\in.txt' > out.txt
para imprimir o arquivo reduzido em um arquivo de saída.O Perl também pode fazer isso:
Este programa imprimirá a primeira linha de sua entrada e a cada terceira linha posteriormente.
Para explicar um pouco,
<>
é o operador de entrada de linha, que itera sobre as linhas de entrada quando usado em umwhile
loop como este. A variável especial$.
contém o número de linhas lidas até o momento e%
é o operador do módulo.Esse código pode ser escrito de forma ainda mais compacta como uma linha, usando as opções
-n
e-e
:O
-e
switch usa um pedaço de código Perl para executar como um parâmetro de linha de comando, enquanto o-n
switch envolve implicitamente o código em umwhile
loop como o mostrado acima.Edit: Para obter as linhas 1, 3, 6, 9, ... como no exemplo, em vez das linhas 1, 4, 7, 10, ... como eu assumi que você queria, substitua
$. % 3 == 1
por$. == 1 or $. % 3 == 0
.fonte
Se você quiser fazer isso com um script Bash, tente:
Salve-o como "read_lines.sh" e lembre-se de conceder + x permissões ao arquivo bash.
fonte
./read_lines.sh > new_file.txt
.Uma solução no bash puro, que não gera um processo, é:
A primeira linha pula 2 linhas no início do arquivo e
while
imprime a próxima linha e pula 2 linhas novamente.Se o seu arquivo for pequeno, é uma maneira muito eficiente de fazer o trabalho, pois não inicia um processo. Quando seu arquivo é grande,
sed
deve ser usado, pois é mais eficiente no manuseio io do quebash
.fonte
Uma versão Python (ambos Python 2 e Python 3):
substitua
[::3]
pelos parâmetros de tamanho inicial, final e da etapa para obter mais controle. Por exemplo,[10:36:5]
coloca as linhas 10,15, ..., 35.Observe que, como
readlines()
mantém as terminações da linha, a saída dessa chamada pode terminar com uma última linha vazia, a menos que a última linha original seja eliminada pelo tamanho da etapa escolhida.Também é possível uma versão de fluxo (aqui é emitida somente após o fluxo final):
fonte