perl -F, -lane '
exists $h{$F[0]} or $h[$h{$F[0]}=@h]=$_;
$h=$_; /,false$/ or $_=$h for $h[$h{$F[0]}];
END{ print for @h; }
' duplicates.file
Estructuras de datos:
- Hash
%h
cuyas claves son los primeros campos (AAA, BBB, CCC, etc.) y los valores correspondientes son números que indican el orden en que se encontraron las claves. Así, por ejemplo, clave AAA => 0, clave BBB => 1, clave CCC => 2.
- Matriz
@h
cuyos elementos son líneas contenidas en el orden de impresión. Entonces, si se encuentran tanto verdadero como falso en los datos, entonces el valor falso irá a la matriz. OTW, si hay un tipo de datos, entonces estaría presente.
Otra forma es usar GNU sed:
sed -Ee '
G
/^([^,]*),(false|true)\n(.*\n)?\1,\2(\n|$)/ba
/^([^,]*)(,true)\n(.*\n)?\1,false(\n|$)/ba
/^([^,]*)(,false)\n((.*\n)?)\1,true(\n|$)/{
s//\3\1\2\5/;h;ba
}
s/([^\n]*)\n(.*)$/\2\n\1/;s/^\n*//
h;:a;$!d;g
' duplicates.file
FWIW, el código POSIX equivalente para el código GNU-sed anterior se enumera a continuación:
sed -e '
G
/^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2$/ba
/^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2\n/ba
/^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2$/ba
/^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2\n/ba
/^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false$/ba
/^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false\n/ba
/^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true$/{
s//\3\1\2/
h
ba
}
/^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true\n/{
s//\3\1\2\n/
h
ba
}
y/\n_/_\n/
s/\([^_]*\)_\(.*\)$/\2_\1/;s/^_*//
y/\n_/_\n/
h;:a;$!d;g
' duplicates.file
Explicación
- En este método almacenamos el resultado para que finalmente se imprima en el espacio de espera.
- Para cada lectura de línea, agregamos el espacio de espera al espacio de patrón para examinar la línea actual en relación con el estado existente del espacio de espera.
- Ahora 5 cosas pueden suceder durante esta comparación:
- a) La línea actual coincide en algún lugar de la línea de retención y falso: falso.
- [ACCIÓN] Dado que se encuentra el mismo estado falso, no haga nada.
- b) La línea actual coincide en algún lugar de la línea de retención y verdadero: verdadero.
- [ACCIÓN] Dado que se encuentra el mismo estado verdadero, no haga nada.
- c) La línea actual coincide en algún lugar de la línea de retención y verdadero: falso.
- [ACCIÓN] Como ya existe un estado falso, no hagas nada.
- d) La línea actual coincide en algún lugar de la línea de retención y falso: verdadero.
- [ACCIÓN] Esto implica algo de trabajo, ya que necesitamos reemplazar la línea falsa en la misma posición exacta donde se encuentra el verdadero.
- e) La línea actual NO coincide en ningún lugar de la línea de retención.
- [ACCIÓN] Mueve la línea actual hasta el final.
Resultados
AA,false
BB,false
CC,false
DD,true
true
si es la primera instancia de la primera columna?AA,true AA,false AA,false AA,false
¿Qué salida debería ser en este caso? Entiendo que esa fila debe eliminarse solo si tiene duplicados y contienetrue
al mismo tiempo. Todas lasfalse
filas deben permanecer intactas en cualquier caso. Es decir, en este caso, soloAA, true
se eliminará. Pero todas las respuestas dejan solo una línea -AA,false
. Simplemente interesante :)