Uma pergunta sobre o awk

9

Ok, já que esta é uma questão complexa, explicarei isso claramente. Eu tenho um conteúdo de arquivo mostrado abaixo:

$ Cat File1 
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}

A saída que eu quero

-Cool MNB +  POP ;
-Cool MNB  + POP ;
-Cool MNB  + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD +POP ;

Primeiramente eu tento tirar a última coluna do File1 e imprimi-la por sed 's/[{}//g' File1 > File3

Depois disso, copio todo o conteúdo de File1 para um novo File4

cp File1 File4

Depois disso, eu substituo os dados dentro do File4 pelos File3 data (significa que os dados sem o colchete um " File1 last column that one")

awk 'FNR==NR{a[NR]=$1;next}{$5=a[FNR]}1' File3 File4 >>File5 

O resultado deve ser assim

ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP TBMKF
ABC Cool Lol POP YUKER
ABC Cool Lol POP EFEFVD

Por fim, tento

awk -F“ " '{print - $2,$5 +,$4 ";"}‘ File5

Mas o resultado não saiu como mostrado como eu quero, apenas os dados semelhantes MNB estão todos listados, outros não apareceram (arquivo de dados uma última coluna), não tenho certeza do que está errado, espero que todos possam ajudar me se você sabe e pode me guiar de uma maneira mais gentil. Meu jeito de fazer isso é bem longo.

    
por heng960407 15.09.2016 / 15:22

4 respostas

16

Eu não sei porque você está copiando as coisas para a esquerda e para a direita. O simples é

awk '{print "-" $2, substr($5,2,length($5)-2), "+", $4, ";"}' File1

Eu coloco o - no começo e o ; no final.

Entre nós imprimimos

  • $2 porque queremos como é.
  • uma substring de $5 , que é o string sem o primeiro e o último caractere. Nós pulamos o primeiro personagem começando na posição 2 (awk sempre foi estranho sobre isso) e deixar de fora o último caractere, selecionando apenas um substring que é dois caracteres menor que o original $5
  • o + porque queremos
  • e, em seguida, $4

No entanto, não tenho certeza se todas essas funções de string são específicas do GNU awk.

    
por 15.09.2016 / 15:43
7

com sed

sed '
    s/\S\+\s/-/
    s/\(\S\+\s\)\{2\}{\(\S\+\)}/ + ;/
    ' File1

E variação awk

awk -F"[[:blank:]{}]+" '{print "-" $2, $5, "+", $4}' ORS=" ;\n" File1
    
por 15.09.2016 / 15:53
6

Trabalho fácil TXR :

$ txr -c '@(repeat)
@a @b @c @d {@e}
@(do (put-line '-@b @e + @d ;'))
@(end)' -
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}
[Ctrl-D][Enter]
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD + POP ;

Usando o TXR Lisp macro awk para transliterar a solução Awk:

 txr -e '(awk (t (prn '-@[f 1] @{[f 4] [1..-1]} + @[f 3] ;')))'

Os campos estão na lista f e a indexação é baseada em zero.

    
por 15.09.2016 / 19:27
3

O uso do awk é mais fácil quando os campos $1,$2,... já contêm as cadeias exatas com as quais você deseja trabalhar. O separador de campo, se contiver mais de um caractere, é interpretado como uma expressão regular. Nós não precisamos fazer nenhuma pesquisa e substituição ou operações de substring para se livrar das {chaves]. Nós apenas os contamos como parte do delimitador.

awk -F'[ {}]+' '{printf("-%s %s + %s ;\n", $2, $5, $4)}'

Usar printf em vez de print também facilita a visualização de como a string será formatada, mas se você quiser ter print "-"$2,$5" + "$4";" em vez de printf("-%s %s + %s ;\n", $2, $5, $4) , essa é uma opção.

    
por 16.09.2016 / 01:37