Como eu corrijo muitos e poucos caracteres de espaço?

2

Eu tenho arquivos editados por outras pessoas além de mim. Eles contêm linhas que se parecem com isso:

<E> This is text </E>

Eu uso alguns scripts de shell Bash para fazer um monte de funções de substituição de texto nessas linhas de texto. No entanto, para que as substituições de texto funcionem, o formato deve estar exatamente correto. Na maior parte do tempo eles são, mas é claro que eu não posso confiar nos editores dos quais estou obtendo esses arquivos para não cometer erros de digitação.

Parte desse formato é que haja um espaço após <E> e um espaço antes de </E> . Nem mais nem menos. Então, tudo isso está incorreto:

<E>This is text </E>
<E> This is text</E>
<E> This is text     </E>
<E>   This is text </E>

Eu sei que posso usar sed para pesquisar problemas específicos , como dois espaços antes de </E> (usando # em vez de / desde o texto em que estou atuando também contém / caracteres):

sed -i '$ s#  </E>#" </E>#g' *.txt

... mas não sei como usá-lo para procurar um número desconhecido. Além disso, nos casos em que não há espaço, o caractere adjacente a <E> ou </E> pode ser qualquer coisa.

Linha de fundo, como eu posso procurar por instâncias de espaços zero e de dois ou mais espaços separados o texto e <E> e </E> tags, e convertê-los em um espaço?

    
por Questioner 21.02.2013 / 03:38

4 respostas

3
sed -e 's!<E> *!<E> !g' -e 's! *</E>! </E>!g'

(Nota: usei ! em vez de # ou / como meu delimitador de expressão regular. Preferência pessoal.)

sed pode receber mais de um comando para ser executado em sua entrada, contanto que cada um seja prefixado com o sinalizador -e .

O * após o espaço nas expressões regulares acima significa "corresponde a 0 ou mais caracteres de espaço". A página re_format man fornece mais informações sobre essa repetição:

An atom followed by '*' matches a sequence of 0 or more matches of the atom. An atom followed by '+' matches a sequence of 1 or more matches of the atom. An atom followed by '?' matches a sequence of 0 or 1 matches of the atom.

em que um "átomo" é o sub-padrão antes do * , + ou ? .

A executar este comando sed nos seus exemplos:

reedm@www:/tmp $ cat > example.txt
<E>This is text </E>
<E> This is text</E>
<E> This is text     </E>
<E>   This is text </E>
reedm@www:/tmp $ sed -e 's!<E> *!<E> !g' -e 's! *</E>! </E>!g' example.txt 
<E> This is text </E>
<E> This is text </E>
<E> This is text </E>
<E> This is text </E>
    
por 21.02.2013 / 05:11
2

echo $STRING | tr -s " "

deve eliminar vários caracteres de espaço consecutivos e reduzi-los a um único espaço. Então cabe a você decidir como deseja lidar com esse único espaço em branco.

espero que isso ajude

    
por 21.02.2013 / 03:57
2

"pelo menos um espaço" é / \+/

"zero ou mais espaços" é / */

"não é um espaço" é /[^ ]/

"two or more spaces" is either /   */ or /  \+/
    
por 21.02.2013 / 03:57
1

Veja as expressões regulares tratadas por sed(1) . Sob as muitas opções que você tem, há \+ para repetir as 1 ou mais vezes anteriores. Portanto, sed -i -e 's; \+</E>;</E>;g' *.txt excluirá qualquer número de espaços antes de </E> . Veja o manual de informações sobre o GNU sed (acho que o pinfo(1) é o melhor leitor, mas o YMMV), a página man definitivamente está faltando. Na listagem detalhada do nó, selecione "Expressões regulares".

    
por 21.02.2013 / 03:59