9
votes

Awk remplacer une colonne avec sa valeur hachage

Comment puis-je remplacer une colonne avec sa valeur de hachage (comme MD5) dans awk ou sed?

Le fichier d'origine est super énorme, alors j'ai besoin que cela soit vraiment efficace.


0 commentaires

5 Réponses :


4
votes

Alors, vous ne voulez pas vraiment faire cela avec awk code>. Toute des langues de script de haut niveau populaires - Perl, Python, Ruby, etc. - ferait cela de manière plus simple et plus robuste. Cela dit, quelque chose comme ça fonctionnera.

Entrée donnée comme ceci: p> xxx pré>

(par exemple, une ligne avec quatre colonnes), nous pouvons remplacer une colonne donnée avec sa somme de contrôle MD5 comme ceci: p> xxx pré>

Ceci s'appuie sur GNU AWK (vous aurez probablement ceci par défaut sur un système Linux), et il utilise openssl code> pour générer la somme de contrôle MD5. Nous construisons d'abord une ligne de commande shell dans TMP code> pour transmettre la colonne sélectionnée dans la commande MD5 code>. Ensuite, nous tuyons la sortie dans la variable code> CLSUM CODE> et remplacez la colonne 2 avec la somme de contrôle. Compte tenu de l'entrée d'échantillon ci-dessus, la sortie de ce script AWK serait la suivante: P>

this 7e1b6dbfa824d5d114e96981cededd00 a test


6 commentaires

C'est vraiment le mauvais genre de chose pour Awk. Votre temps serait mieux dépensé avec l'une des autres langues que j'ai mentionnées.


Je vois plusieurs problèmes avec cette solution. Pour une chose, si la colonne ( 2 $ ) contient des méta-caractères shell, il peut faire des choses inattendues. L'utilisation de citations simples ne résout pas entièrement ceci (le champ pourrait contenir des guillemets simples). Et en utilisant echo plutôt que echo -n signifie que vous obtiendrez le MD5Sum du champ avec une nouvelle ligne ajoutée ( 7e1b ... est Le MD5Sum de "est \ n" , pas de "est" .)


Avec Perl, vous pouvez utiliser un module qui fait des checksums MD5 sans appeler un programme externe - ou, si vous préférez, vous pouvez appeler un programme externe sans passer à travers la coque ( perdoc perlfuncuncunc et recherchez " système").


... Et c'est pourquoi j'ai commencé avec (et suivi de) le fait que ce problème n'est pas vraiment quelque chose qui convient à Awk.


Cette solution a créé des processus de défunts pour chaque ligne traitée. Quelqu'un sache comment prévenir cela?


Trouvé ça. gnu.org/software/gawk/manual/ html_node / ... Vous devez fermer manuellement le fichier



2
votes

Ceci pourrait fonctionner à l'aide de Bash / GNU SED:

<<<"this is a test" sed -r 'h;s/^\S+\s(\S+).*/md5sum <<<"\1"/e;G;s/^(\S+).*\n(\S+)\s\S+\s(.*)/\2 \1 \3/'
this 7e1b6dbfa824d5d114e96981cededd00 a test


4 commentaires

Qu'est-ce que '/ e dans le premier exemple? Est-ce un drapeau SED? Je ne peux pas l'obtenir pour travailler et obtenir de Bash Invite: SH: 1: Erreur de syntaxe: Redirection inattendue


@martin the E sur une commande de substitution est spécifique à GNU et évalue l'espace de motif (suivant la substitution) comme si elle était dans la coque actuelle.


Merci mais de toute façon, l'erreur ci-dessus se produit toujours de mon côté avec le premier exemple que vous avez fourni.


Eh bien, sur mon hôte, il semble que la substitution se déroule dans "SH" plutôt que "Bash" pour une raison quelconque, d'où je publie la commande de bash sur la ligne de commande.



1
votes

Vous pourriez avoir un meilleur moment avec lire code> que awk code>, bien que je n'ai pas fait de benchmarking.

L'entrée (gratter001.txt): p> xxx pré>

transformé à l'aide de lire code>: p> xxx pré>

produit la sortie: p>

foo|bar|3858f62230ac3c915f300c664312c63f|baz|bang|bazbang
baz|bang|19e737ea1f14d36fc0a85fbe0c3e76f9|foo|bar|foobar


0 commentaires

5
votes

Je copie la réponse de Larsks collé, mais j'ai ajouté la ligne de fermeture, pour éviter le problème indiqué dans ce post: GAWK / AWK: Date de la tuyauterie à GetLeLe * Parfois * Ne fonctionnera pas

awk '{
    tmp="echo " $2 " | openssl md5 | cut -f2 -d\" \""
tmp | getline cksum
close(tmp)
$2=cksum
print
}' < sample 


1 commentaires

C'est en train de passer le contenu de 2 $ à la coque non noté, il est donc ouvert à la globe globale, au scission de travail, à une injection de code malveillante, etc. (Utilisez TMP = "echo \ 047 .. . à la place) et utilise getline d'une manière qui va bien corrompre votre sortie si elle échoue de quelque manière que ce soit, voir awk.freeshell.org/allaboutgetline pour quand / Comment utiliser getline .



1
votes

Vous pouvez également faire cela avec Perl:

echo "aze qsd wxc" | perl -MDigest::MD5 -ne 'print "$1 ".Digest::MD5::md5_hex($2)." $3" if /([^ ]+) ([^ ]+) ([^ ]+)/' 
aze 511e33b4b0fe4bf75aa3bbac63311e5a wxc


0 commentaires