Como as letras indesejadas podem ser removidas de um documento com sed?

1

Eu tenho uma lista que é uma saída de um programa de mídia e eu quero remover todo o lixo para que eu possa usar essa lista para o meu script Zenity, mas envolve um monte de comandos sed em uma string que é a maneira que eu prefiro im abra qualquer sugestão que envolva apenas sed.

Vou explicar exatamente o que estou tentando ter sucesso:

A lista atual é List.txt: O * é apenas hex 1b

*line here is not needed*
*[1m0  *[22m : *[35mThis has SPACES inside, Must be DOTS!*[39m : *[34m123.123ABCD*[39m
*[1m1  *[22m : *[35mThis-DONT-have(SPACES)-inside*[39m : *[34m900.578CD*[39m
*[1m2  *[22m : *[35mThis SPACE!!! inside, # Must be DOTS!*[39m : *[34m9K99123AD*[39m
*[1m3  *[22m : *[35mSPACES *Must* be DOTS!*[39m : *[34mAB*[39m
*[1m4  *[22m : *[35mMust[be] [DOTS] !*[39m : *[34m12.AZZZ*[39m
*[1m5  *[22m : *[35mSPACES ~DOTS!*[39m : *[34m654KK45*[39m

Esta é a minha equação de sed:

cat ~/List.txt | sed -e 1d -e 's/\x1b\[1m//g' -e 's/\x1b\[22m : \x1b\[35m/|---|/g' -e 's/\x1b\[39m : /|---| /g' -e 's/.|---|*//' -e 's/|---|*//' -e 's/\x1b*\[34m/(/g' -e 's/\x1b\[39m/)/g' -e 's/^/FALSE /' -e '0,/FALSE /s//TRUE /' > sedList.txt

Este é o sedList.txt que tem espaços entre as palavras:

TRUE 0 This has SPACES inside, Must be DOTS! (123.123ABCD)
FALSE 1 This-DONT-have(SPACES)-inside (900.578CD)
FALSE 2 This SPACE!!! inside, # Must be DOTS! (9K99123AD)
FALSE 3 SPACES *Must* be DOTS! (AB)
FALSE 4 Must[be] [DOTS] ! (12.AZZZ)
FALSE 5 SPACES ~DOTS! (654KK45)

Eu quero substituir esses espaços por pontos no local específico ( não tudo ) para que o sedList.txt pareça exacly assim:

TRUE 0 This.has.SPACES.inside,.Must.be.DOTS! (123.123ABCD)
FALSE 1 This-DONT-have(SPACES)-inside (900.578CD)
FALSE 2 This.SPACE!!!.inside,.#.Must.be.DOTS! (9K99123AD)
FALSE 3 SPACES.*Must*.be.DOTS! (AB)
FALSE 4 Must[be].[DOTS].! (12.AZZZ)
FALSE 5 SPACES.~DOTS! (654KK45)

Então, o que está faltando na equação sed eu devo adicionar algo?

    
por GoldHaloWings 23.10.2017 / 21:31

5 respostas

2

Eu acho que você estava quase lá, eu apenas substituí todos os espaços por pontos primeiro.

sed -e 1d \
        -e 's/\s/./g' \
        -e 's/x1b\[1m0/TRUE 0/g' \
        -e 's/x1b\[1m/FALSE /g' \
        -e 's/\.\./ /g' \
        -e 's/\!x1b\[39m/\!/g' \
        -e 's/x1b\[34m/\(/g' \
        -e 's/x1b\[39m/\)/g' \
        -e 's/x1b\[22m\.\:\.x1b\[35m//g' \
        -e 's/\.\./\./g' \
        -e 's/\.\:\./ /g' \
~/List.txt > SEDList.txt
    
por olivierb2 23.10.2017 / 22:22
1

Como você pede sed :

sed -re 1d \
  -e 's/\x1b\[[0-9]+m//g' \
  -e 'y/ /./' \
  -e 's/^([0-9]+)\.*:\./FALSE  /'\
  -e 's/\.:\.(.*)/ ()/'\
  -e '1s/FALSE/TRUE/'
    
por muru 24.10.2017 / 07:28
1

Este produz o resultado desejado:

sed '1d;s/\x1b\[[0-9]*m//g;s/  *: /\n/g;y/ /./;s/^/FALSE /;2s/FALSE/TRUE/;s/$/)/;s/\n/ /;s// (/' yourfile

Minhas dicas para você:

  • Primeiro de tudo: não cat e pipe para sed . Em vez disso, dê o nome do arquivo como argumento para sed .
  • Em seguida, manipule todas as sequências de escape de uma só vez com uma expressão regular como \x1b\[[0-9]*m para simplificar seu script
  • Evite padrões "mágicos" como seu |---| . Com o GNU sed , você pode usar a nova linha. Isso é único e fácil de manusear.

Versão comentada:

sed '1d;                # drop the first line
     s/\x1b\[[0-9]*m//g;# remove all esc sequences
     s/  *: /\n/g;      # replace the colons with spaces by newlines
     y/ /./;            # replace the spaces with dots
     s/^/FALSE /;       # add the 'FALSE' to the beginning
     2s/FALSE/TRUE/;    # except for the second line
     s// (/;            # first separator becomes space
     s/$/)/;            # second becomes space with (
     s/\n/ /;           # finally the trailing )' yourfile
    
por Philippos 24.10.2017 / 09:35
0

Embora o seguinte não seja tão rápido quanto uma única chamada sed , ele adiciona flexibilidade.

sed \
    -e 1d  \
    -re 's/\x1b\[[0-9]+m//g' \
    -e 's/:/ /g' List.txt |
awk '{
    if (=="0")
        {printf("TRUE "" "); for (i=2; i<=(NF-1); i++) printf("%s%s",".",$i); printf(" ("$NF")\n")}
    else
        {printf("FALSE "" "); for (i=2; i<=(NF-1); i++) printf("%s%s",".",$i); printf(" ("$NF")\n")}
    }' |
sed 's/ \./ /g' > SEDList.txt

Como uma única linha utilizável em um script.

"$( sed -e 1d -re 's/\x1b\[[0-9]+m//g' -e 's/:/ /g' "$TheList" | awk '{ if (=="0") {printf("TRUE "" "); for (i=2; i<=(NF-1); i++) printf("%s%s",".",$i); printf(" ("$NF")\n")} else {printf("FALSE "" "); for (i=2; i<=(NF-1); i++) printf("%s%s",".",$i); printf(" ("$NF")\n")} }' | sed 's/ \./ /g' )"
    
por J. Starnes 24.10.2017 / 07:01
0

Eu vejo essa questão como composta de 2 problemas: (1) remover o ansi-seq e (2) ajustar e limpe o formato. A primeira parte ofusca o segundo.

Aqui, dê apenas uma resposta parcial: sugiro o uso de ansifilter para uma limpeza inicial de sequências ansi:

ansifilter ~/List.txt | ...
    
por JJoao 07.11.2017 / 00:34