Comment puis-je remplacer une colonne avec sa valeur de hachage (comme MD5) dans awk ou sed? p>
Le fichier d'origine est super énorme, alors j'ai besoin que cela soit vraiment efficace. P>
5 Réponses :
Alors, vous ne voulez pas vraiment faire cela avec Entrée donnée comme ceci: p> (par exemple, une ligne avec quatre colonnes), nous pouvons remplacer une colonne donnée avec sa somme de contrôle MD5 comme ceci: p> Ceci s'appuie sur GNU AWK (vous aurez probablement ceci par défaut sur un système Linux), et il utilise 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.
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
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 $ code>) 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 code> plutôt que
echo -n code> signifie que vous obtiendrez le MD5Sum du champ avec une nouvelle ligne ajoutée (
7e1b ... code> est Le MD5Sum de
"est \ n" code>, pas de
"est" code>.)
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 recherche> 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
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
Qu'est-ce que '/ e code> 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 code>
@martin the E code> 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.
Vous pourriez avoir un meilleur moment avec L'entrée (gratter001.txt): p> transformé à l'aide de produit la sortie: p> lire code> que
awk code>, bien que je n'ai pas fait de benchmarking.
lire code>: p>
foo|bar|3858f62230ac3c915f300c664312c63f|baz|bang|bazbang
baz|bang|19e737ea1f14d36fc0a85fbe0c3e76f9|foo|bar|foobar
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
C'est en train de passer le contenu de 2 $ code> à 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 .. . code> à la place) et utilise
getline code> 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 code>.
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