Removendo caracteres especiais do arquivo e mantendo o separador de campos

2

Eu consegui remover todos os caracteres especiais de um arquivo de tamanho fixo que aparece na primeira coluna, mas como resultado, todas as colunas subseqüentes foram deslocadas para a esquerda pela quantidade de caracteres excluídos. É um arquivo separado por espaço. A linha 1 no arquivo de entrada está corrompida. A linha 2 é como deve ser. A cadeia 000022000362700 começa na posição 49 em ambas as linhas. O problema que estou tendo é que depois de remover os 3 caracteres especiais, o campo se move para a posição 46.

GAVISCON LIQUID PEPPERMINT �OT        000022000362700   159588000007979400  50001584182        0006S020000
GAVISCON LIQUID PEPPERMINT OT           000022000362700   159588000007979400  50001584182        0006S020000

O comando que estou usando é o seguinte:

cat file.txt | grep '[^ - ~]' | sed's/[^ - ~]//g'

Isso produz a seguinte saída:

    GAVISCON LIQUID PEPPERMINT OT        000022000362700   159588000007979400  50001584182        0006S020000

Ao remover os caracteres especiais, todos os campos à direita do campo alterado foram movidos para a esquerda, alterando as posições iniciais do campo.

Estou procurando há algum tempo e não consigo encontrar nenhuma solução para esse problema.

Como devo proceder?

    
por Irfan Salim 21.04.2015 / 12:45

2 respostas

1

Use este comando:

sed -r 's/(\^|-|~)/ /g' file.txt
  • sed -r

    -r, --regexp-extended
    use expressões regulares estendidas no script

  • / / a espaço como seu separador de campo (ou qualquer outra string)

  • (\^|-|~)

    • 1º grupo de captura (\^|-|~)

      • 1ª alternativa: \^

        \^ corresponde ao caractere ^ literalmente

      • 2ª alternativa: -

        - corresponde ao caractere - literalmente

      • 3ª alternativa: ~

        ~ corresponde ao caractere ~ literalmente

Uma outra variante é essa (Thx @Costas ):

sed 's/[-~^]/ /g' file.txt
  • [^-~]

    • [-~^] corresponde a um único caractere presente na lista abaixo

      -~^ um único caractere na lista -~^ literalmente

por 21.04.2015 / 13:00
1

sed's/[^ - ~]//g' provavelmente não é o comando que você usou, porque ele apenas reclamaria de um comando inválido. Sempre copie e cole!

Eu presumo que você tenha executado sed 's/[^ -~]//g' . Isso substitui qualquer caractere que não seja um caractere ASCII imprimível por uma cadeia vazia. Em outras palavras, isso remove todos os caracteres que não são caracteres ASCII imprimíveis. (Observe que isso é verdadeiro na localidade padrão, ou seja, em LC_ALL=C , mas não é o caso em muitas outras localidades.)

Para manter as colunas alinhadas, substitua cada caractere não imprimível por um espaço.

sed 's/[^ -~]/ /g'

Devido ao comando grep , somente as linhas que continham caracteres não imprimíveis aparecerão na saída. Você não precisa de grep . Passe todas as linhas para sed ; as linhas que não precisam ser modificadas aparecerão no lugar certo na saída.

<file.txt LC_ALL=C sed 's/[^ -~]/ /g' >new-file.txt

Isso adiciona espaços no meio das colunas, por exemplo você vai acabar com

GAVISCON LIQUID PEPPERMINT    OT        000022000362700   159588000007979400  50001584182        0006S020000

Se você quiser que os espaços acabem à direita da coluna, por exemplo

GAVISCON LIQUID PEPPERMINT OT           000022000362700   159588000007979400  50001584182        0006S020000

você precisará de uma abordagem diferente, onde você indica onde as colunas param. Embora isso possa ser feito no sed, é muito mais fácil no awk. Veja como você pode remover caracteres não imprimíveis da primeira coluna e manter os dados das outras colunas começando na posição 49.

<file.txt LC_ALL=C awk '{
    first_column = substr($0, 1, 48);
    gsub(/[^ -~]/, "", first_column);
    printf "%-48s%s\n", first_column, substr($0, 49)
}' >new-file.txt
    
por 22.04.2015 / 02:43

Tags