¿Cómo fusionar texto de líneas alfabéticas con líneas numéricas en Shell?

¿Cómo fusionar texto de líneas alfabéticas con líneas numéricas en Shell?

Tengo un archivo que tiene un texto como este:

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

etc...

Y quiero hacer coincidir las líneas alfabéticas con las líneas numéricas para que queden así:

AAAA 1234 
BBBB 5678
CCCC 9012
DDDD 3456

EEEE 7890

¿Alguien conoce una forma sencilla de lograr esto?

Respuesta1

En awk, se conservan las líneas vacías, suponiendo que el archivo esté bien formateado, pero se podría agregar lógica para verificar el archivo:

awk -v RS="" '{for(i=1; i<=NF; i++) a[i]=$i
  getline
  for(i=1; i<=NF; i++) print a[i] " " $i
  print ""}' file

Respuesta2

<input sed -nr '/^[A-Z]{4}$/,/^$/w out1
                /^[0-9]{4}$/,/^$/w out2'
paste -d' ' out1 out2 |sed 's/^ $//' 

o, en un solo paso, sin archivos temporales

paste -d' ' <(sed -nr '/^[A-Z]{4}$/,/^$/p' input) \
            <(sed -nr '/^[0-9]{4}$/,/^$/p' input) | sed 's/^ $//' 

El último sedpaso elimina el delimitador de las líneas en blanco, que se introduce mediante paste...

Respuesta3

Una forma usando perl:

Contenido de script.pl:

use warnings;
use strict;

## Check arguments.
die qq[Usage: perl $0 <input-file>\n] unless @ARGV == 1;

my (@alpha, @digit);

while ( <> ) {
        ## Omit blank lines.
        next if m/\A\s*\Z/;

        ## Remove leading and trailing spaces.
        s/\A\s*//;
        s/\s*\Z//;

        ## Save alphanumeric fields and fields with
        ## only digits to different arrays.
        if ( m/\A[[:alpha:]]+\Z/ ) {
                push @alpha, $_;
        }
        elsif ( m/\A[[:digit:]]+\Z/ ) {
                push @digit, $_;
        }
}

## Get same positions from both arrays and print them
## in the same line.
for my $i ( 0 .. $#alpha ) {
        printf qq[%s %s\n], $alpha[ $i ], $digit[ $i ];
}

Contenido de infile:

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

Ejecútelo como:

perl script.pl infile

Y resultado:

AAAA 1234
BBBB 5678
CCCC 9012
DDDD 3456
EEEE 7890

Respuesta4

Si las entradas están en orden,

  1. Divida la entrada en entradas alfabéticas y numéricas, usando grep:

    • grep "[[:alpha:]]\+" < file > alpha
    • grep "[[:digit:]]\+" < file > digit
  2. Une los dos archivos resultantes alphay digit, usando paste:

    • paste alpha digit(puedes agregarlo -d " "para que use un espacio en lugar de una pestaña)

información relacionada