É possível remover caracteres repetidos específicos de uma lista usando regex?

É possível remover caracteres repetidos específicos de uma lista usando regex?

Eu tenho uma lista de uma coluna que contém ~ 100 linhas, nas quais algumas linhas são repetidas, e meu objetivo é me livrar de umespecíficolinhas duplicadas e deixe apenasumcópia, enquanto as outras linhas permaneceram intactas.

Um extrato dos arquivos nos quais estou trabalhando:

V(Mn9)   
V(C1,H3) 
V(Mn6)   
V(Mn6)   
V(C4,H6) 
V(Mn9)   
V(Mn9)   
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)   
V(C1,C4) 
C(Mn9)   
C(Mn6)   
C(C1)    
C(C4)    
C(Mn9)   
C(Mn6)   
V(C1,H2) 
V(Mn9)   
V(Mn6)   
V(C4,H5)

Meu objetivo é remover todas as linhas duplicadas que contêm C(Xx0-9) e deixar uma delas e manter o V(Xxx..).

O resultado que procuro:

V(Mn9)   
V(C1,H3) 
V(Mn6)   
V(Mn6)   
V(C4,H6) 
V(Mn9)   
V(Mn9)   
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)   
V(C1,C4) 
C(C1)    
C(C4)    
C(Mn9)   
C(Mn6)   
V(C1,H2) 
V(Mn9)   
V(Mn6)   
V(C4,H5)

Eu usei o comando:

sed '0,/C(Mn9)/{/C(Mn9)/d}' inputfile.txt | sed '0,/C(Mn6)/{/C(Mn6)/d}'

e está funcionando, mas não é bom o suficiente para o arquivo inteiro, porque tem muito C(Xx1-50), pensei em usar expressão regular, mas não sei como, por isso preciso da sua ajuda.

Responder1

$ awk '!(/^C\(..[0-9])$/ && seen[$0]++)' file
V(Mn9)
V(C1,H3)
V(Mn6)
V(Mn6)
V(C4,H6)
V(Mn9)
V(Mn9)
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)
V(C1,C4)
C(Mn9)
C(Mn6)
C(C1)
C(C4)
V(C1,H2)
V(Mn9)
V(Mn6)
V(C4,H5)

O texto acima pressupõe que você não tenha espaços em branco antes/depois dos caracteres visíveis em sua entrada de amostra. Se você fizer isso, remova-os, por exemplo:

$ awk '{gsub(/^[[:space:]]+|[[:space:]]+$/,"")} !(/^C\(..[0-9])$/ && seen[$0]++)' file
V(Mn9)
V(C1,H3)
V(Mn6)
V(Mn6)
V(C4,H6)
V(Mn9)
V(Mn9)
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)
V(C1,C4)
C(Mn9)
C(Mn6)
C(C1)
C(C4)
V(C1,H2)
V(Mn9)
V(Mn6)
V(C4,H5)

Responder2

Sugiro usar sedpara coletar linhas no espaço de espera para verificar se elas apareceram antes:

 sed -n 'H;G;/^\(C([^)]*)\).*\1 *\n/!P'
  • Hanexa a linha atual ao espaço de espera
  • Ganexa o espaço de espera com todas as linhas que já vimos ao espaço do padrão
  • C([^)]*)é um desses C(…)padrões, o ^ancora no início da linha e é cercado por \(…\), para que possa ser referenciado \1posteriormente. Precisamos \1 *\nde um padrão, com a nova linha (após possíveis espaços em branco) para evitar a correspondência com a linha recém-anexada no final. Portanto, todo o padrão /^\(C([^)]*)\).*\1 *\n/corresponde a uma linha com um duplicado C(…), portanto, somente se isso !não corresponder,
  • Pimprimir tudo antes da primeira nova linha (= sem o espaço de espera anexado), enquanto a saída padrão é suprimida pela -nopção

Observe que dependendo da sedversão e do tamanho do arquivo, isso pode falhar porque, com o tempo, todas as linhas estarão na memória.

informação relacionada