¿Es posible eliminar caracteres repetidos específicos de una lista usando expresiones regulares?

¿Es posible eliminar caracteres repetidos específicos de una lista usando expresiones regulares?

Tengo una lista de una columna que contiene ~ 100 líneas, en la que algunas líneas se repiten, y mi propósito es deshacerme de unespecíficoduplicar líneas y dejar solounocopia, mientras que las otras líneas se mantienen intactas.

Un extracto de los archivos en los que estoy trabajando:

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)

Mi propósito es eliminar todas las líneas duplicadas que contienen C(Xx0-9) y dejar una de ellas y conservar la V(Xxx...).

El resultado que busco:

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)

Usé el comando:

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

y está funcionando, pero no es lo suficientemente bueno para todo el archivo, porque hay mucho C(Xx1-50), pensé en usar una expresión regular, pero no sé cómo, por eso necesito tu ayuda.

Respuesta1

$ 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)

Lo anterior supone que no tiene espacios en blanco antes/después de los caracteres visibles en su entrada de muestra. Si es así, elimínelos, por ejemplo:

$ 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)

Respuesta2

Sugiero utilizar sedpara recopilar líneas en el espacio de espera para comprobar si aparecieron antes:

 sed -n 'H;G;/^\(C([^)]*)\).*\1 *\n/!P'
  • Hagrega la línea actual al espacio de espera
  • Gagrega el espacio de retención con todas las líneas que vimos al espacio del patrón
  • C([^)]*)es uno de esos C(…)patrones, ^lo ancla al principio de la línea y está rodeado por \(…\), por lo que se puede hacer referencia a él \1más adelante. Necesitamos \1 *\ncomo patrón, con la nueva línea (después de posibles espacios en blanco) para evitar que coincida con la línea recién agregada al final. Entonces todo el patrón /^\(C([^)]*)\).*\1 *\n/coincide con una línea con un duplicado C(…), así que solo si esto !no coincide,
  • P-nimprime todo antes de la primera nueva línea (= sin el espacio de retención agregado), mientras que la opción suprime la salida predeterminada

Tenga en cuenta que, dependiendo de su sedversión y tamaño de archivo, esto puede fallar porque, con el tiempo, todas las líneas estarán en la memoria.

información relacionada