Como @mjv conjeturó - awk (o Perl, Python o) es una mejor opción:
awk -F';' ' {
if (assoc[$2]) { # This field 2 has been seen before
if (assoc[$2] != 1) { # The first occurrence has not been printed
print assoc[$2]; # Print first line with given $2
assoc[$2] = 1; # Reset array entry so we know we've printed it;
# a full line has 8 fields with semi-colons and
# cannot be confused with 1.
}
print $0; # Print this duplicate entry
}
else {
assoc[$2] = $0; # Record line in associative array, indexed by
# second field.
}
}' <<!
a;b;c;d;e;f;g;h
a;c;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;2;c;d;e;f;g;h
a;z;c;d;e;f;g;h
a;q;c;d;e;f;g;h
a;4;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;x;c;d;e;f;g;h
a;c;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;q;c;d;e;f;g;h
a;4;c;d;e;f;g;h
!
Esto funciona, pero puede volver a ordenar un poco los datos - ya que imprime la primera aparición de una línea duplicada cuando aparece la segunda aparición La salida de la muestra es:
a;1;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;c;c;d;e;f;g;h
a;c;c;d;e;f;g;h
a;1;c;d;e;f;g;h
a;q;c;d;e;f;g;h
a;q;c;d;e;f;g;h
a;4;c;d;e;f;g;h
a;4;c;d;e;f;g;h
Esta variante de la secuencia de comandos awk
vuelve a organizar la prueba, lo que lleva a una notación ligeramente más compacto. También ignora explícitamente líneas de datos mal formadas que no contienen 8 campos separados por punto y coma. Está empaquetado como un script de shell, pero sin ningún tipo de manejo de opciones, por lo que solo puede proporcionar una lista de archivos para escanear (lee la entrada estándar si no hay archivos en la lista). Eliminé los puntos y coma Perl-ish en el script; awk
no los necesita.
#!/bin/sh
awk -F';' '
NF == 8 {
if (!assoc[$2]) assoc[$2] = $0
else if (assoc[$2] != 1)
{
print assoc[$2]
assoc[$2] = 1
print $0
}
else print $0
}' "[email protected]"
Además, @mjv comentó que podría haber problemas de memoria con una solución como ésta si la entrada es enorme, ya que mantiene un registro de cada valor distinto de campo 2 en la matriz asociativa 'Assoc'. Podemos eliminar eso si los datos alimentados en awk
están ordenados, algo que podemos asegurar usando sort
, por supuesto.Aquí hay un script variante que no lidiar con entradas monstruosas (porque sort
derrames de datos en el disco si es necesario para mantener los resultados intermedios):
sort -t';' -k 2,2 "[email protected]" |
awk -F';' '
BEGIN { last = ";"; line = "" }
NF == 8 {
if ($2 != last)
{
last = $2
line = $0
}
else if (line != "")
{
print line
line = ""
print $0
}
else print $0;
}'
Esto sólo se conserva una copia de una línea de entrada. El resultado de los datos de muestra se da en orden ordenado, por supuesto.
No tengo bieleve Tengo esa herramienta. Cuando escribo "awk --help" no recibo tal mensaje de opción – goe
Hum ... tal vez tienes boquiabierto, que de hecho es "mejor" (en mi humilde opinión) – mjv
gawk tampoco existe – goe