Substituir usando vim - Substituir um padrão […] por uma string

4

Eu tenho um arquivo contendo linhas abaixo, por ex. formato -

[[email protected], [email protected]], Payment processed - 23499, params = {'invoice':3243}

Eu só quero os números da conta, ou seja, 23499. É um número. Digamos que <account> . Não é uma constante.

Por isso, estou tentando -

  1. Remover params ...
  2. Substituir [...] do início de cada linha por espaço em branco

Por ... , quero dizer qualquer string. Eu tentei -

# 1
:%s/params.*//g
# 2
:%s/\<[]\>//g
:%s/\<\[\]\>//g
:%s/\<[.*]\>//g
:%s/\<\[.*\]\>//g

Todas as coisas que tentei em # 2 não funcionaram. O que estou fazendo de errado? Como obtenho <account> ? Me ajude.

    
por Hussain Tamboli 25.09.2014 / 17:02

4 respostas

2

Você pode usar a seguinte sequência para reter apenas os números da conta (do cudo a J.D.Mohr)
anote o espaço após o r no comando

:%norm $F,d$Bhv0r 

Isso pressupõe que haja apenas um , após o número que você deseja reter

Repartição

:     -> Enter command mode
%norm -> Applies a normal command to the entire file
$     -> Jump to end of line
F,    -> Find preceding ,
d$    -> Delete until end of line
B     -> Jump back a word
hv0   -> Go left one character and select until beginning of line
r     -> replace selected text with <space>
    
por 25.09.2014 / 18:05
0

Para obter apenas a string <account>

awk '{print $6}' file| sed 's/,//' >> newfile

Para possível uso futuro dos dados principais, isso pode ser útil

    
por 25.09.2014 / 17:10
0

Se você procurar <account> (algo como <12345> ) e tiver < e > somente em <account> , como era na versão original da pergunta, isso poderia funcionar :

%s/\v.*(\<.*\>).*//

Corresponde < e > com qualquer coisa entre - que esteja em um grupo, e qualquer coisa antes e depois na linha. Isso é substituído apenas pelo grupo.

Respondendo a pergunta atualizada:

Se você não tem <account> , mas um número neste lugar, sem < e > : isso funciona de maneira semelhante:

%s/\v.* - ([0-9]*), params =.*//

Ele combina números, em um grupo para mantê-los. E corresponde a qualquer coisa antes que termine com "-", e qualquer coisa depois disso começa com , params = , ambos até o início ou fim da linha.
Portanto, a expressão corresponde à linha inteira e é substituída pelo grupo correspondente que contém o número.

Está usando \v para expressões regulares "muito mágicas", veja :help /magic .

    
por 25.09.2014 / 17:20
0

Por mais fácil que seja usar vim (ou sed para isso), awk é realmente totalmente capaz de fazer esse tipo de correspondência e substituição por conta própria:

$ awk '{ sub(/^.* - /, ""); sub(/,.*$/, ""); print $0 }' file
23499

Os itens acima correspondem a tudo (com awk embutido sub() função ) desde o início da linha até o hífen e espaço antes do número da conta e o substitui pela string vazia "" . Em seguida, ele combina tudo, desde a vírgula até o final da linha e a substitui pela string vazia. Isso deve ser robusto (por exemplo, independentemente de quantos e-mails ou qual seja o formato deles), remova tudo, exceto o número da conta.

Se você tiver acesso a gawk , poderá usar uma solução mais simples (somente uma chamada de função é necessária):

$ gawk 'match($0, /^.* - ([0-9]+),.*$/, a) { print a[1] }' file
23499

É claro que as soluções acima imprimem os novos dados para stdout . Se você quiser salvar os novos dados para uso posterior, tudo o que você precisa fazer é adicionar > newfile ao final do comando acima (observe que > sobrescreve; se você preferir acrescentar, use >> ).

awk tem muitas limitações próprias (por exemplo, trabalhar com muitos arquivos ao mesmo tempo), por isso nem sempre é a melhor ferramenta para esse tipo de manipulação. No entanto, é muito bom no que faz, por isso, quando o seu caso de uso estiver alinhado com o round-house, recomendo vivamente a sua utilização.

Além disso, a solução acima não requer nenhuma interface interativa (como vim ) e nenhuma tubulação.

    
por 25.09.2014 / 18:00