Adicione um símbolo antes de qualquer letra

4

Eu tenho um arquivo de texto com cada linha tendo um número definido de campos, mas eles podem diferir de linha para linha. Tudo o que quero fazer é adicionar "=" sinal na frente de todos os valores no campo nessa linha.

Por exemplo ARQUIVO DE ENTRADA

A   B   C   D   E
P   Q   R   S   T   U
L   M   N   O

ARQUIVO DE SAÍDA

=A  =B  =C  =D  =E
=P  =Q  =R  =S  =T  =U
=L  =M  =N  =O

Além disso, este é apenas um exemplo, meu arquivo contém algumas linhas em que o número de campos é maior que 20. Como fazer isso com eficiência.

    
por user3138373 14.05.2014 / 17:10

6 respostas

4

Para fazer isso em awk , você poderia usar:

awk '{for (i=1;i<=NF;i++) printf "=%s ",$i;printf "\n"}' filename

Faça o loop sobre a variável interna NF (number of fields), imprimindo cada campo com um igual prefixado e um espaço anexado e, depois de imprimir todos os campos, imprima uma nova linha.

    
por 14.05.2014 / 17:22
7

Supondo que seus campos contenham mais do que apenas uma letra, com GNU sed :

sed 's/\</=/g' <<END
foo    bar    baz
A      B      C
apple  banana cherry
END
=foo    =bar    =baz
=A      =B      =C
=apple  =banana =cherry

A construção \< regex do GNU sed é um marcador "início da palavra" de largura zero (a transição entre uma não palavra (ou o início da linha) e um caractere de palavra (alnums na sua localidade ou sublinhado)) . Então, estamos substituindo o início de cada palavra pelo caractere "=".

(referência do regex de sed aqui )

    
por 14.05.2014 / 19:01
5

Uma versão awk mais curta:

$ awk 'gsub(/([^ ]+)/,"=&",$0)' file
=A   =B   =C   =D   =E
=P   =Q   =R   =S   =T   =U
=L   =M   =N   =O

Explicação

Fazemos uma substituição global para cada linha de entrada:

  • /([^ ]+)/ : corresponde a cada campo porque os campos são separados por espaços, portanto, essa regex corresponde a todas as outras, exceto espaços.

  • "=&" : com cada campo, adicione = antes.

& meaning é substituído pelo caractere que foi correspondido. De man awk :

gsub(r, s [, t])        For each substring matching the regular expres‐
                        sion  r  in the string t, substitute the string
                        s, and return the number of substitutions.   If
                        t  is  not  supplied,  use  $0.   An  &  in the
                        replacement text is replaced with the text that
                        was  actually matched.  Use \& to get a literal
                        &.  (This must be typed  as  "\&";  see  GAWK:
                        Effective  AWK Programming for a fuller discus‐
                        sion of the rules for &'s  and  backslashes  in
                        the replacement text of sub(), gsub(), and gen‐
                        sub().)

Atualizar

Para a resposta e comentário de @glenn jackman, adiciono uma versão equivalente em perl :

$ perl -pe 's/\b(?=\w)/=$&/g' file
=A   =B   =C   =D   =E
=P   =Q   =R   =S   =T   =U
=L   =M   =N   =O
    
por 14.05.2014 / 18:05
2

Sua pergunta não está muito clara.

Para inserir = antes de cada sequência de letras, seria:

sed 's/[[:alpha:]]\{1,\}/=&/g'

Antes de qualquer carta:

sed 's/[[:alpha:]]/=&/g'

Antes de cada sequência de não espaços em branco:

sed 's/[^[:blank:]]\{1,\}/=&/g'

(esses são POSIX e portáteis).

    
por 14.05.2014 / 20:26
1

Experimente este comando sed simples,

sed 's/\([A-Za-z]\+\)/=/g' file

Exemplo:

$ (echo 'A   B   C'; echo 'A C D F') | sed 's/\([A-Za-z]\+\)/=/g'
=A   =B   =C
=A =C =D =F

Este comando colocará o sinal = antes de A-Z , a-z .

OR

experimente este comando também,

sed 's/\([ ]\+\)/=/g; s/^\(.*\)$/=/g' file

Exemplo:

$ (echo 'A   B   C'; echo 'A C D F') | sed 's/\([ ]\+\)/=/g; s/^\(.*\)$/=/g'
=A   =B   =C
=A =C =D =F

Esse comando substituirá um ou mais espaços com um ou mais espaços, além de = sign e também colocará = na inicialização.

    
por 14.05.2014 / 17:15
1

Você pode simplificar isso um pouco com o GNU awk

awk -v RS='[[:space:]]+' '{printf "=%s%s", $0,RT}' input.file
=A   =B   =C   =D   =E
=P   =Q   =R   =S   =T   =U
=L   =M   =N   =O
    
por 14.05.2014 / 17:39

Tags