2011-11-06 28 views

Respuesta

2

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 
4

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 
+0

Gracias amigo ... Necesito trabajar en mis habilidades de awk ... aún queda mucho camino por recorrer :-) – Amir

+0

Esto es realmente el tipo equivocado de awk. Su tiempo sería mejor utilizado con uno de los otros idiomas que mencioné. – larsks

+1

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 "'.) –

2

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.

+0

¿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

+0

@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

+0

gracias, pero de todos modos, el error anterior aún sucede en mi lado con el primer ejemplo que proporcionó. – martin

1

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 
1

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.

Cuestiones relacionadas