Aquí hay uno divertido. Puede usar sed
directamente para quitar todas las copias de la primera línea y dejar todo lo demás en su lugar (incluida la primera línea).
sed '1{h;n;};G;/^\(.*\)\n\1$/d;s/\n.*$//' input
1{h;n;}
coloca la primera línea en el espacio de espera, la imprime y lee en la siguiente línea, omitiendo el resto de los sed
comandos para la primera línea. (También omite esa primera 1
prueba para la segunda línea , pero eso no importa ya que esa prueba no se aplicaría a la segunda línea).
G
agrega una nueva línea seguida del contenido del espacio de retención al espacio del patrón.
/^\(.*\)\n\1$/d
elimina el contenido del espacio del patrón (saltando así a la siguiente línea) si la porción después de la nueva línea (es decir, lo que se agregó desde el espacio de retención) coincide exactamente con la porción anterior a la nueva línea. Aquí es donde se eliminarán las líneas que duplican el encabezado.
s/\n.*$//
elimina la porción de texto que agregó el G
comando, de modo que lo que se imprime es solo la línea de texto del archivo.
Sin embargo, dado que la expresión regular es costosa, un enfoque un poco más rápido sería usar la misma condición (negada) y P
alinearse con la nueva línea si la porción después de la nueva línea (es decir, lo que se agregó desde el espacio de espera) no coincide exactamente con la porción antes de la nueva línea y luego elimine incondicionalmente el espacio del patrón:
sed '1{h;n;};G;/^\(.*\)\n\1$/!P;d' input
La salida cuando se le da su entrada es:
ID Data1 Data2
1 100 100
2 100 200
3 200 100
4 100 100
5 200 200
{ IFS= read -r head; printf '%s\n' "$head"; grep -vF "$head" ; } <file