¿Extraer (y volcar a la salida estándar) solo un cierto rango de filas de un CSV?

¿Extraer (y volcar a la salida estándar) solo un cierto rango de filas de un CSV?

Tengo un archivo CSV de aproximadamente 1000 filas, y donde se supone que debo importarlo, aparece un error en la fila 700. Sin embargo, las entradas en este CSV contienen nuevas líneas (y están entrecomilladas) y, por lo tanto, no puedo usarlas rápidamente awko similar para mostrar cuál es la fila 700.

Entonces encontré¿Existe una herramienta sólida de línea de comandos para procesar archivos csv?, e instalé ambos csvfixy csvkit; sin embargo, parece que ninguna de estas aplicaciones admite simplemente especificar un número de fila (o un rango de filas) y generarlas. Por ejemplo:

$ csvfix help echo
echo input CSV data to output
usage: csvfix echo [flags] [file ...]
where flags are:
  -ibl      ignore blank input lines
  -sep s    specify CSV field separator character
  -rsep s   as for -sep but retain separator on output
  -osep s   specifies output separator
  -hdr s    write the string s out as a header record
  -ifn      ignore field name record
  -smq      use smart quotes on output
  -sqf fields   specify fields that must be quoted
  -o file   write output to file rather than standard output
  -skip t   if test t is true, do not process or output record

Habría pensado echoque es lo que necesito, tan pronto como pude especificar qué fila(s) se va a repetir, pero cuando mirohttp://neilb.bitbucket.org/csvfix/manual/csvfix16/csvfix.html?unique.html, solo se describen las columnas.

¿Cómo podría usar estas herramientas, u otras herramientas, para simplemente volcar, por ejemplo, la fila 700 (o las filas 702-705) de un CSV de 1000 filas a la salida estándar?


EDITAR: Encontrado (http://neilb.bitbucket.org/csvfix/manual/csvfix16/ExpressionLanguage.html) que csvfixtiene:

csvfix find -if '$line == 407' data.csv

... sin embargo, este es de hecho el número de línea y no el número de fila; entonces, si la fila comienza en la línea 406, luego pasa a la línea 407 y termina en 407; entonces el comando anterior no generará nada, pero si retrocede una línea, -if '$line == 406'la fila se descarta. Esto también es útil, pero todavía no es un número de fila...

Respuesta1

El comando csvfix findadmite el volcado de una fila por rango o número. El siguiente comando extraería las líneas 3 y 4 de un archivo llamado file.csv.

csvfix find -if '$line >= 3 && $line < 5' file.csv

Respuesta2

Puede eliminar temporalmente todas las nuevas líneas entre comillas para poder utilizar las herramientas de texto normales y volver a agregar las nuevas líneas.

Por ejemplo, en caso de comillas dobles:

gawk -v RS='"' 'NR % 2 == 0 { gsub(/\n/, "%NEWLINE%") } { printf("%s%s", $0, RT) }' file.csv > tmp.csv
head -n 700 tmp.csv | sed 's/%NEWLINE%/\n/g' > file_1-700.csv

Respuesta3

Puede obtener una posición del Text::CSV_XS de Perl de esta manera:

perl -MText::CSV_XS -E 'open(my $fh, "<:encoding(utf8)", $ARGV[0]) or die "open: $!"; $csv = Text::CSV_XS->new({binary => 1, auto_diag => 9, diag_verbose => 1 } ); while (my $row = $csv->getline($fh)) { say tell $fh }' FILENAME.csv

Tenga en cuenta el FILENAME.csval final de la línea.

Después de analizar con éxito cada fila, imprimirá elbytecompensar.

Desembalaje del resumen:

use Text::CSV_XS;
use feature 'say';
open(my $fh, '<:encoding(utf8)', $ARGV[0]) or die "open: $!";
$csv = 'Text::CSV_XS'->new({'binary' => 1, 'auto_diag' => 9, 'diag_verbose' => 1});
while (my $row = $csv->getline($fh)) {
    say tell $fh
}

Le alimenté este CSS defectuoso ( new.css):

r1c1,"r1
c2",r1c3
r2c1,"r2c2,r2c3
r3c1,r3c2,r3c3

Producción:

18
# CSV_XS ERROR: 2027 - EIQ - Quoted field not terminated @ rec 1 pos 15 field 2

(Si hubiera más filas buenas antes de la corrupta, se imprimirían más compensaciones de bytes. Utilice la última).

Entonces, después del byte 18, encontró un error. Es bastante fácil obtener un número de línea a partir de eso: head -c 18 new.csv | wc -l, que dice 2 (el número de líneas buenas). Entonces el error está en la línea 3, y de hecho lo está, la cita alrededor de r2c2 no está cerrada.

información relacionada