Como mesclar texto de linhas alfabéticas com as linhas numéricas no shell?

10

Eu tenho um arquivo com texto como este:

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

etc ...

E eu quero combinar as linhas alfabéticas com as linhas numéricas, então elas são assim:

AAAA 1234 
BBBB 5678
CCCC 9012
DDDD 3456

EEEE 7890

Alguém sabe de uma maneira simples de conseguir isso?

    
por NWS 24.03.2012 / 14:56

7 respostas

3

Uma maneira de usar perl :

Conteúdo 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 ];
}

Conteúdo de infile :

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

Execute como:

perl script.pl infile

E resultado:

AAAA 1234
BBBB 5678
CCCC 9012
DDDD 3456
EEEE 7890
    
por 24.03.2012 / 16:10
4

Em awk , preservando as linhas vazias, assumindo que o arquivo está bem formatado, mas a lógica pode ser adicionada para verificar o arquivo:

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
    
por 24.03.2012 / 20:14
4
<input sed -nr '/^[A-Z]{4}$/,/^$/w out1
                /^[0-9]{4}$/,/^$/w out2'
paste -d' ' out1 out2 |sed 's/^ $//' 

ou, em uma única etapa, sem arquivos temporários

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

A última etapa sed remove o delimitador nas linhas em branco, introduzidas por paste ...

    
por 24.03.2012 / 16:11
3

Com o emacs use operações de retângulo para cortar as linhas de texto e colá-las antes das linhas numéricas.

    
por 24.03.2012 / 15:00
2

Se as entradas estiverem em ordem,

  1. Divida a entrada em entradas alfabéticas e entradas numéricas, usando grep :

    • grep "[[:alpha:]]\+" < file > alpha
    • grep "[[:digit:]]\+" < file > digit
  2. Junte os dois arquivos resultantes, alpha e digit , usando paste :

    • paste alpha digit (você pode adicionar -d " " para usar um espaço em vez de uma guia)
por 24.03.2012 / 15:59
1

Muito ruim o awk não tem funções push / pop / unshift / shift. Aqui está um pequeno snippet Perl

perl -M5.010 -lne '
  given ($_) {
    when (/^[[:alpha:]]+$/) {push @alpha, $_}
    when (/^\d+$/) {say shift(@alpha), " ", $_}
    default {say}
  }
'
    
por 26.03.2012 / 04:08
0

Dê um arquivo com texto, tente usar pr e sintaxe de substituições do processo conforme abaixo:

$ pr -mt <(grep -i "^[a-z]" file.txt) <(grep -i "^[0-9]" file.txt)
AAAA                    1234
BBBB                    5678
CCCC                    9012
DDDD                    3456
EEEE                    7890

Você pode ajustar a largura em -w9 ou remover espaços em sed "s/ //g" .

    
por 05.05.2015 / 17:15