cClaude.rocks ☕ Le blog

[Nouvelles technologies, sciences et coups de gueule…]

Menu

Contexte

La recherche de doublons est un besoin assez frĂ©quent, l’implĂ©mentation en bash n’est pas nĂ©cessairement simple.

Je vous propose une solution trùs simple à mettre en Ɠuvre utilisant jq.


ඏ

Exemples

Pour rechercher une valeur en double, il faut mĂ©moriser cette valeur qu’on appellera la clĂ© et garder il faut Ă©galement mĂ©moriser un identificateur correspondant Ă  cette valeur.

De maniĂšre gĂ©nĂ©rale, vous devrez donc prĂ©voir du code pour construire la valeur de la clĂ© et un mĂ©canisme pour construire l’identificateur.

Cas d’un fichier texte

Supposons un fichier texte dans lequel on souhaite retrouver les lignes en doubles, sans changer l’ordre du fichier.

Dans ce cas la valeur Ă  mĂ©moriser est le contenu de la ligne (ce sera notre clĂ©) et l’identificateur sera, par exemple, le numĂ©ro de la ligne.

Il sera possible, par exemple, de supprimer les derniùres lignes en double, sans pour autant changer l’ordre du fichier.

Cas de fichiers sur le disque

Si on souhaite rechercher des fichiers ayant le mĂȘme contenu dans une arborescence donnĂ©e, la clĂ© devient le contenu du fichier, comme cela n’est pas acceptable (trop de mĂ©moire et trop lent), on passe par un calcul de hachage, par exemple Ă  l’aide de sha512sum et, dans ce cas, l’identificateur sera le nom du fichier.


ඏ

L’algorithme

Initialisation

L’initialisation est Ă  faire une seule fois au dĂ©but du traitement. On va utiliser une variable globale pour rĂ©pondre au cas gĂ©nĂ©ral.

declare -g _entries_json_='{}'

Il s’agit ici de construire un objet JSON vide.

Itération

_key_=
Le truc potentiellement en double

_id_=
Un truc permettant d’identifier les doubles

_entries_json_="$(
  jq -c --arg key "${_key_}" --arg id "${_id_}" '.[$key] |= .+ [ $id ]' <<<"${_entries_json_}"
  )"

Attention, la clĂ© doit est une chaĂźne de caractĂšre raisonnable : en particulier, elle ne doit pas ĂȘtre trop longue.

RĂ©sultat

Une fois toutes les valeurs stockĂ©es dans la structure JSON, on supprime toutes les entrĂ©es qui n’ont pas de double :

_resultat_="$(
  jq '[ to_entries[] | select( .value | length >1 ) ] | from_entries' <<<"${_entries_json_}"
  )"

Et pour dĂ©tecter s’il y a des doubles, il suffit regarder le nombre d’entrĂ©es, par exemple :

if [ -n "$( jq -r 'to_entries[] | length' <<<"${_resultat_}" )" ] ; then
  echo 'Les doubles:'
  jq '.' <<<"${_resultat_}"
else
  echo 'Pas de double'
fi

Exemple de code concret

La bibliothĂšque:

function init_duplicate {
  declare -g _entries_json_='{}'
}

function add_for_duplicate {
  local -r _key_="$1"
  local -r _id_="$2"

  _entries_json_="$(
    jq -c --arg key "${_key_}" --arg id "${_id_}" '.[$key] |= .+ [ $id ]' <<<"${_entries_json_}"
    )"
}

function finalize_duplicate {
  _entries_json_="$(
    jq '[ to_entries[] | select( .value | length >1 ) ] | from_entries' <<<"${_entries_json_}"
    )"
}

Imaginons le code suivant :

init_duplicate

add_for_duplicate 'k1' 'v1-1'
add_for_duplicate 'k1' 'v1-2'
add_for_duplicate 'k2' 'v1-2'
add_for_duplicate 'k2' 'v2-2'
add_for_duplicate 'k3' 'v3-1'

jq '.' <<<"${_entries_json_}"

Le résultat intermédiaire sera :

{
  "k1": [ "v1-1", "v1-2" ],
  "k2": [ "v2-1", "v2-2" ],
  "k3": [ "v3-1" ]
}

Ensuite pour obtenir que les doubles, on peut faire :

finalize_duplicate

jq '.' <<<"${_entries_json_}"

Et voilà :

{
  "k1": [ "v1-1", "v1-2" ],
  "k2": [ "v1-2", "v2-2" ]
}

ඏ

Utilisation de la mémoire

Cette solution est assez gourmande en mĂ©moire et en CPU, mais il est trĂšs facile de l’adapter et de stocker le rĂ©sultat dans un fichier (au dĂ©triment du temps d’exĂ©cution, bien Ă©videment).

Le principal intĂ©rĂȘt de cette solution Ă©tant qu’elle est assez gĂ©nĂ©rique et s’adapte Ă  presque tous les cas.


ඏ

Références

኿


â„č 2006 - 2021 | 🏠 Retour Ă  l'accueil du domaine | 🏡 Retour Ă  l'accueil du blog