2010-01-13 28 views
6

Escribí una secuencia de comandos perl usando Tie :: Handle :: CSV para procesar un conjunto de datos en un archivo csv e imprimir solo lo que necesito en un nuevo archivo csv. En este momento, imprimo la línea de cabecera con todos los nombres de campo por sólo un hardcoding en este modo:Imprimir encabezado CSV con Tie :: Handle :: CSV

print '"TERM", "STUDENT ID", "NAME", ..."'."\n"; 

Sospecho que esto es una manera tonta de hacer esto, pero no sé cómo obtener acceso al encabezado desde el objeto Tie :: Handle :: CSV. Se crea una instancia como tal,

my $fh = Tie::Handle::CSV->new($file,header=> 1); 

y se accede a los datos como tal,

$line -> {'CATALOG_NBR'} 

Sé lo suficiente para saber que esto es un hash-referencia, pero no lo suficiente para saber cómo imprimir el encabezado de utilizar este en lugar de hardcoding. Obviamente, "ellos" generalmente cambian los nombres precisos de las columnas y el orden justo después de que el script vuelva a funcionar cada término.

¡Muchas gracias por cualquier ayuda! JA

Respuesta

3

Si se define el encabezado y no una referencia de matriz, la primera línea del documento se utilizará como encabezado. Lamentablemente, no existe un método para obtener el encabezado original, por lo que no es suficiente leer la primera línea usando la opción de encabezado como falsa, almacenarla (ya es una referencia de matriz) y cerrar el archivo y volver a leerlo, no lo hago ver una manera más fácil de hacerlo.

use strict; 
use warnings; 
use Tie::Handle::CSV; 
use Data::Dumper; 

my $csv_fh = Tie::Handle::CSV->new('basic.csv', header => 0); 
my $header = <$csv_fh>; 
close $csv_fh; 
print join(',', @$header), "\n"; 

$csv_fh = Tie::Handle::CSV->new('basic.csv', header => 1); 
while (my $csv_line = <$csv_fh>) { 
    # $csv_line can be used here 
    ... 
} 
close $csv_fh; 
+0

Gracias chicos - terminé haciendo esencialmente una combinación de sus consejos. Abrí dos manejadores de archivo - el segundo $ hfh con encabezado => 0 para poder imprimir las etiquetas de encabezado en el orden correcto como así: my $ fh = Tie :: Handle :: CSV-> new ($ file , encabezado => 1); my $ hfh = Tie :: Handle :: CSV-> new ($ file, header => 0); my $ line = <$hfh>; my $ header; foreach (@ {$ line}) { $ header. = "\" $ _ \ ","; } print "$ header \ n"; ¡Gracias nuevamente por su ayuda! – Jason

2

De acuerdo con the documentation, parece que apagar header => 1 en su constructor hará que no analice el encabezado. A continuación, debe obtener los nombres de las columnas del encabezado como el primer $line devuelto por el objeto.

También significa que sus $line s serán referencias de matriz en lugar de referencias de hash, por lo que necesita para mostrar los valores posicionales con $line->[0], $line->[1], y así sucesivamente, en lugar de utilizar los nombres de encabezado.

Si desea utilizar la opción header => 1, puede obtener las claves hash con my @headers = keys %{ $line }. Tenga en cuenta que no hay garantía de que las claves estén en un orden particular, por lo que tendrá que encontrar la manera de ordenarlas usted mismo.

No he usado realmente este módulo, así que esto es toda una conjetura basada en la lectura de la documentación para la opción header.

+0

, gracias - Terminé haciendo esencialmente una combinación de su consejo. Abrí dos identificadores de archivo, el segundo $ hfh con encabezado => 0 para poder imprimir las etiquetas de encabezado en el orden correcto, así: my $ fh = Tie :: Handle :: CSV-> new ($ file, header => 1); my $ hfh = Tie :: Handle :: CSV-> new ($ file, header => 0); my $ line = <$hfh>; mi $ encabezado; foreach (@ {$ line}) {$ header. = "\" $ _ \ ","; } print "$ header \ n"; ¡Gracias nuevamente por tu asistencia! – Jason

1

Gracias chicos - terminé haciendo esencialmente una combinación de sus consejos. Abrí dos identificadores de archivo - el segundo $ hfh con la cabecera => 0 por lo que podía imprimir las etiquetas de cabecera en el orden correcto de este modo:

my $fh = Tie::Handle::CSV->new($file, header => 1); 
my $hfh = Tie::Handle::CSV->new($file, header=>0); 
my $line = <$hfh>; 
my $header; 
foreach(@{$line}) { 
    $header .= "\"$_\","; 
} 
print "$header\n"; 

Gracias de nuevo por su ayuda!

6

Llegué un poco tarde a la fiesta, pero acabo de lanzar una nueva versión de Tie::Handle::CSV (debería estar activa en CPAN dentro de unas horas). Agrega soporte para un método header(), que devuelve un encabezado con formato CSV.Uso podría ser:

my $fh = Tie::Handle::CSV->new($file, header => 1); 
    print $fh->header; 

Espero que esto ayude,

  • danboo
  • chicos
+1

¡Eso es fantástico! Muchas gracias, funciona como un encanto. Aprecio mucho esto - Jason – Jason