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
Structures de données:
- Hash
%h
dont les clés sont des premiers champs (AAA, BBB, CCC, etc.) et les valeurs correspondantes sont des nombres indiquant l'ordre dans lequel les clés ont été rencontrées. Ainsi, par exemple, clé AAA => 0, clé BBB => 1, clé CCC => 2.
- Tableau
@h
dont les éléments sont des lignes contenues dans l'ordre d'impression. Donc, si à la fois vrai et faux sont trouvés dans les données, la fausse valeur ira dans le tableau. OTW, s'il y a un type de données, alors ce serait présent.
Une autre façon utilise 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, le code équivalent POSIX pour le code GNU-sed ci-dessus est répertorié ci-dessous:
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
Explication
- Dans cette méthode, nous stockons le résultat pour qu'il soit finalement imprimé dans l'espace d'attente.
- Pour chaque ligne lue, nous ajoutons l'espace de maintien à l'espace de motif pour examiner la ligne actuelle par rapport à l'état existant de l'espace de maintien.
- Maintenant, 5 choses peuvent éventuellement se produire pendant cette comparaison:
- a) La ligne actuelle correspond quelque part dans la ligne d'attente et false: false.
- [ACTION] Puisque le même faux état est trouvé, alors ne faites rien.
- b) La ligne actuelle correspond quelque part dans la ligne d'attente et true: true.
- [ACTION] Puisque le même vrai état est trouvé, alors ne faites rien.
- c) La ligne actuelle correspond quelque part dans la ligne d'attente et true: false.
- [ACTION] Puisqu'un faux état existe déjà, ne faites rien.
- d) La ligne actuelle correspond quelque part dans la ligne d'attente et false: true.
- [ACTION] Cela implique un certain travail, en ce que nous devons remplacer la fausse ligne à la même position exacte où se trouve le vrai.
- e) La ligne actuelle ne correspond à aucun endroit de la ligne d'attente.
- [ACTION] Déplacer la ligne actuelle jusqu'à la fin.
Résultats
AA,false
BB,false
CC,false
DD,true
true
si c'est la première instance de la première colonne?