• Publicidad

Editar ficheros .dat en un solo .dat y por columnas

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor explorer » 2012-03-18 15:31 @688

enric73 escribiste:De esta manera la primera línea de los diferentes ficheros planos no se conserva... ¿Tiene alguna relación con el HeaderRow?
¡Oops! Algo estaba mal... Corregido más abajo.

enric73 escribiste:Al final del proceso, querría añadir en la fila 1 del fichero final con la fecha del año (yyyymmddhh), ¿qué comando me recomienda que al introducir esta fila no me borre el resto? Ya tengo instalado el Class::Date
A ver... ¿A qué te refieres exactamente? ¿Insertar una línea delante de todas con la fecha? ¿O que esa fecha la insertemos solo en la primera columna, en la primera posición?

En el ejemplo que te pongo a continuación, insertamos una nueva fila al principio.

enric73 escribiste:Otra consulta, al ejecutar el script, se genera de forma paralela un carpeta llamada cache/ con ficheros UGRD*.dat.cache, ¿para qué sirven?
Eso se desactiva con la opción _CacheOnRead. El sistema de caché de este módulo es por si, más adelante, necesitas volver a leer los mismos archivos. El módulo se dará cuenta de que existe una copia prefabricada en el cache/, y lo leerá de allí.

La ventaja es que las lecturas desde el cache/ son mucho más rápidas que leyendo el archivo original. Sobre todo se nota si tienes archivos con miles o millones de datos.



Existe otro problema que no hemos comentado hasta ahora: este módulo toma por defecto la primera línea de cada archivo como el nombre de la columna. Podría darse el caso de que más de un archivo contuviera el mismo valor en la primera fila, y por lo tanto, el módulo sacaría un mensaje de error diciendo que no puede combinar esos archivos porque tienen el mismo nombre de columna. Si estás completamente seguro de que eso no se va a dar nunca, el programa lo puedes dejar tal cual. Pero si no es así, entonces el programa exige que tengamos creada, antes de la combinación, el listado de nombres de las columnas que vamos a leer. Podría ser algo tan simple como números: '1', '2', '3'... Y luego, en la salida, ponemos el _HeaderRow => 0, y los datos salen sin esas cabeceras.

Juntándolo todo, quedaría así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use Data::CTable;
  3. use POSIX 'strftime';
  4.  
  5. my $tabla = Data::CTable->new();                         # Objeto Data::CTable
  6.  
  7. my @archivos = </home/sam/enric/ASCII/UGRD*>;            # listado de los archivos
  8. #print "Uniendo ", scalar(@archivos), " archivos\n";
  9.  
  10. # Combinación
  11. for my $i ( 1 .. @archivos ) {                           # hacemos un bucle por todos ellos
  12.     $tabla->combine_file( $archivos[$i-1], {             # combinamos un archivo
  13.         _HeaderRow   => 0,                               # que no tiene cabecera
  14.         _FieldList   => [ $i ],                          # porque la prefabricamos
  15.         _CacheOnRead => 0,                               # y no queremos caché
  16.     });
  17. }
  18. # aquí ya tenemos toda la tabla, con todas las columnas, cuyos nombres son 1, 2, 3, ...
  19.  
  20. # Ponemos la fecha
  21. my $largo = $tabla->length();                            # cómo es de grande esa tabla
  22. $tabla->row_set($largo, {                                # $largo también es el índice de la nueva fila
  23.                                                          # (las filas se numeran de 0 a $largo-1)
  24.     1 => strftime('%Y%m%d%H', localtime),                # en la primera columna de esa fila ponemos la fecha
  25. });
  26. $tabla->row_move($largo, 0);                             # y subimos la fila arriba del todo
  27.  
  28. # Salida
  29. $tabla->write(                                           # escribimos el resultado
  30.     _FileName   => 'vientos.dat',                        # aquí
  31.     _FDelimiter => "\t",                                 # y tabulado
  32.     _HeaderRow  => 0,                                    # pero sin las cabeceras prefabricadas
  33. );
  34. __END__
  35. 2012031821
  36. 1       a       A1
  37. 2       b       B2
  38. 3       c       C3
  39. 4       d       D4
  40. 5       e       E5
  41. 6       f       F6
  42. 7               G7
  43. 8               H8
  44. 9               I9
  45.                 J10
  46.                 K11
  47.                 L12
  48.                 M13
  49.                 N14
  50.                 O15
  51.                 P16
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Publicidad

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-03-18 16:17 @720

¡Muchas gracias explorer!

¡Qué máquina!

Una última consulta: si quiero eliminar una fila, la primera fila de un archivo.dat, no por comando sino desde dentro del script.

Por ejemplo, si quiero eliminar de esta columna, la primera fila que corresponde a 256 17, ¿cómo puedo hacerlo? ¿con la función sed?

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
256 17
35A
45C
45D
43J
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Gracias.
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor explorer » 2012-03-18 16:49 @742

Con la función row_delete($número_de_fila-1) puedes hacerlo.

sed no existe como función, dentro de Perl.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-03-19 02:38 @151

¡Buenos días, explorer, y al resto!

Gracias por el último consejo. He escrito este cortito script para eliminar la primera fila de todos los archivos MET* que se encuentran en un directorio.

He utilizado la subrutina row_delete() pero al lanzar el script no es reconocida.

Posiblemente en la cabecera he de introducir un use con alguna biblioteca...? Si alguien puede aconsejarme, gracias

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2. # ************************************************************************** #
  3. #  Script para eliminar la primera fila                #
  4. # ************************************************************************** #
  5. use Class::Date qw(date now);
  6. use File::Path;
  7.  
  8.  
  9. # ----------------------------------------------------------------------------
  10. # Ruta de los archivos .dat
  11. # ----------------------------------------------------------------------------
  12. #
  13.  
  14.  
  15. my @fitxers = </home/enric/ASCII/MET*>;
  16.  
  17. foreach $fitxer ( @fitxers) {
  18.         open (FITXER, "<$fitxer") or die "$!\n";
  19.         $numero_de_fila=1;
  20.         row_delete($numero_de_fila-1);
  21. ##      chomp(@linies = <FITXER>) ;
  22.         close (FITXER);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor explorer » 2012-03-19 08:38 @401

Me has liado con las preguntas. Pensaba que te seguías refiriendo al problema anterior, por lo que te he dado una solución basada en el problema anterior.

Como hemos usado el módulo Data::CTable, pues aprovechábamos su funcionalidad, y row_delete() pertenece a él.

Ahora lo que estás planteando es un problema nuevo.

Depende un poco del tamaño y el formato de los ficheros, pero una opción podría ser:
* leer todo el archivo en memoria, a un array (una línea por elemento)
* quitar la primera línea, con splice() o con shift()
* escribir el resultado

Pero se me ocurren otras seis formas distintas.

Depende de cómo sean esos archivos...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-03-19 09:43 @446

Hola, buenas tardes.

Se trata de eliminar la primera fila de un conjunto de ficheros MET*.dat que están en un directorio.

Cada fichero contiene unas 50.000 líneas y necesito eliminar la primera que es una cabecera. El fichero empieza así, y quiero eliminar las cifras 360 181.

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
360 181
-1.06
-0.99
-0.92
-0.85
-0.78
-0.71
-0.64
-0.57
-0.5
-0.43
-0.36
-0.29
-0.22
-0.15
-0.08
-0.01
0.06
0.13
0.2
0.27
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Muchas gracias. ¿Hasta 6 maneras se puede eliminar esta línea?
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor Birei » 2012-03-19 09:54 @454

Una manera:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. perl -i.orig -ne 'print unless $. == 1; close ARGV if eof' MET*.dat
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Los archivos originales se guardarán como seguridad añadiendo el sufijo .orig. Usa -i sólo para modificarlos sin crear backups.
Birei
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2011-06-19 13:27 @602

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor enric73 » 2012-03-19 10:50 @493

¡Gracias Birei!

Me ha funcionado. ¿Me podrías explicar un poco más cómo procede esta línea comando? Muchas gracias.

perl -i.orig -ne 'print unless $. == 1; close ARGV if eof' MET*.dat
enric73
Perlero nuevo
Perlero nuevo
 
Mensajes: 154
Registrado: 2012-03-16 06:27 @311

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor explorer » 2012-03-19 11:00 @500

Otra forma:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use autodie;
  2. use Tie::File;
  3.  
  4. tie my @lineas, 'Tie::File', 'kk.txt';         # enlazamos la vida de @lineas con las líneas de kk.txt
  5. shift  @lineas;                                # quitamos la primera línea
  6. untie  @lineas;                                # fin del enlace
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


De todas maneras, ¿seguro que necesitas quitar esa línea?

Es muy posible que no necesites quitarla porque la siguiente fase de procesamiento podría, simplemente, obviarla.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Editar ficheros .dat en un solo .dat y por columnas

Notapor Birei » 2012-03-19 11:02 @501

Explicación:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
-i                      Editar archivos pasados como argumentos.
.orig                   Antes de modificar, guardar el archivo original con extensión 'orig'.
-n                      Por defecto no imprimir nada.
-e                      Ejecutar las siguientes instrucciones.
print unless $. == 1    Imprimir línea salvo que sea la primera del archivo.
close ARGV if eof       Al final del archivo cerrarlo de manera explícita para inicializar el contador de líneas ($.).
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Birei
Perlero nuevo
Perlero nuevo
 
Mensajes: 15
Registrado: 2011-06-19 13:27 @602

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Bing [Bot] y 39 invitados