¿Cómo puedo reemplazar una columna con su valor hash (como MD5) en awk o sed?Awk reemplazar una columna con su valor hash
El archivo original es muy grande, así que necesito que esto sea realmente eficiente.
¿Cómo puedo reemplazar una columna con su valor hash (como MD5) en awk o sed?Awk reemplazar una columna con su valor hash
El archivo original es muy grande, así que necesito que esto sea realmente eficiente.
I copia pegada la respuesta de larsks, pero han añadido la línea de cierre, para evitar el problema indicado en esta publicación: gawk/awk: piping date to getline *sometimes* won't work
awk '{
tmp="echo " $2 " | openssl md5 | cut -f2 -d\" \""
tmp | getline cksum
close(tmp)
$2=cksum
print
}' < sample
Por lo tanto, realmente no desea hacer esto con awk
. Cualquiera de los populares lenguajes de scripting de alto nivel -Perl, Python, Ruby, etc.- lo haría de una forma más simple y robusta. Habiendo dicho eso, algo como esto funcionará.
entrada dada así:
this is a test
(por ejemplo, una fila con cuatro columnas), podemos reemplazar una columna dada con su suma de control MD5 de esta manera:
awk '{
tmp="echo " $2 " | openssl md5 | cut -f2 -d\" \""
tmp | getline cksum
$2=cksum
print
}' < sample
Esto se basa en GNU awk (probablemente tendrá esto por defecto en un sistema Linux), y usa openssl
para generar la suma de comprobación md5. Primero construimos una línea de comando de shell en tmp
para pasar la columna seleccionada al comando md5
. Luego canalizamos la salida a la variable cksum
y reemplazamos la columna 2 con la suma de comprobación. Teniendo en cuenta la entrada de la muestra anteriormente, la salida de este script awk sería:
this 7e1b6dbfa824d5d114e96981cededd00 a test
Esto podría funcionar usando Bash/sed de GNU:
<<<"this is a test" sed -r 's/(\S+\s)(\S+)(.*)/echo "\1 $(md5sum <<<"\2") \3"/e;s/ - //'
this 7e1b6dbfa824d5d114e96981cededd00 a test
o una solución sobre todo 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
Reemplaza is
de this is a test
con md5sum
Explicación:
En el primero: - identifique las columnas y utilice referencias como parámetros en el comando Bash que se sustituye y evalúa y luego realice cambios estéticos para perder la descripción del archivo (en este caso, entrada estándar) generada por el comando md5sum.
En el segundo: similar al primero pero cuelgue la cadena de entrada en el espacio de espera, luego después de evaluar el comando md5sum, agregue la cadena G
al espacio de patrones (md5sum result) y utilice la posición de sustitución adecuada.
¿Qué es ''/ e' en el primer ejemplo? ¿Es una bandera de sed? No puedo hacer que funcione y me sale por mensaje bash: 'sh: 1: Error de sintaxis: redirección inesperada' – martin
@martin el indicador' e' en un comando de sustitución es específico de GNU y evalúa el espacio del patrón (después de la sustitución) como si estuviera en el caparazón actual. – potong
gracias, pero de todos modos, el error anterior aún sucede en mi lado con el primer ejemplo que proporcionó. – martin
Es posible que tenga un mejor momento con read
que awk
, aunque no he hecho ninguna evaluación comparativa.
la entrada (scratch001.txt):
foo|bar|foobar|baz|bang|bazbang
baz|bang|bazbang|foo|bar|foobar
transformó utilizando read
:
while IFS="|" read -r one fish twofish red fishy bluefishy; do
twofish=`echo -n $twofish | md5sum | tr -d " -"`
echo "$one|$fish|$twofish|$red|$fishy|$bluefishy"
done < scratch001.txt
produce la salida:
foo|bar|3858f62230ac3c915f300c664312c63f|baz|bang|bazbang
baz|bang|19e737ea1f14d36fc0a85fbe0c3e76f9|foo|bar|foobar
También puede hacer eso con Perl:
echo "aze qsd wxc" | perl -MDigest::MD5 -ne 'print "$1 ".Digest::MD5::md5_hex($2)." $3" if /([^ ]+) ([^ ]+) ([^ ]+)/'
aze 511e33b4b0fe4bf75aa3bbac63311e5a wxc
Si desea ocultar gran cantidad de datos que puede ser más rápido que la sed y awk que deben desembolsar un proceso md5sum en cada línea.
Gracias amigo ... Necesito trabajar en mis habilidades de awk ... aún queda mucho camino por recorrer :-) – Amir
Esto es realmente el tipo equivocado de awk. Su tiempo sería mejor utilizado con uno de los otros idiomas que mencioné. – larsks
Veo varios problemas con esta solución. Por un lado, si la columna ('$ 2') contiene metacaracteres del shell, puede hacer cosas inesperadas. El uso de comillas simples no resuelve completamente esto (el campo podría contener comillas simples). Y usar 'echo' en lugar de' echo -n' significa que obtendrá el md5sum del campo con una nueva línea anexa ('7e1b ...' es el md5sum de '" es \ n "', no de '" es "'.) –