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?