2012-03-27 11 views
7

Soy nuevo en el lenguaje de programación y cosas así que tengo que invertir con awk todas las líneas y también todas las palabras en esas líneas, desde un archivo e imprimirlas.Awk revertir ambas líneas y palabras

"archivo1" para revertir:

aa bb cc

foo hacer como

y la impresión de salida de la "archivo1" debe ser la siguiente:

como foo

cc bb aa

He intentado esto por palabra invertir en cada línea:

for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)

pero si quiero imprimir las líneas invertidas tengo que hacer esto

{a[NR]=$0 
}END{for(i=NR; i; i--) print a[i]} 

Necesito trabajar con dos archivos con este comando en la terminal:

awk -f commandFile FileToBePrinted 

El problema es que soy principiante en todo esto y no sé cómo combinar esos dos. Gracias!

+0

+1 para la pregunta bien presentada (¡también la primera vez!). ¡Buen formato, entrada de muestra, salida de muestra Y código que no funciona! Buen espectáculo y sigue publicando! – shellter

Respuesta

3

solución de Kev se ve a revertir el texto en cada palabra. Su salida de ejemplo no muestra eso, pero su punto clave es usar una función.

Tiene el código que necesita, solo necesita reorganizarlo un poco.

cat file1 
aa bb cc 
foo do as 

cat commandFile 

function reverse(line) { 
    n=split(line, tmpLine) 
    for (j=n; j>0; j--) { 
    printf("%s ",tmpLine[j]) 
    } 

} 
# main loop 
{ a[NR]=$0 } 

# print reversed array 
END{ for(i=NR; i>0; i--) printf("%s\n", reverse(a[i])) } 

Correr

awk -f commandFile file1 

salida

as do foo 
cc bb aa 

Había un par de pequeños cambios que hice, usando n=split(line, tmpLine) ... print tmpLine[j], es un método común de analizar una línea de entrada en una función para imprimirlo. No creo que los $ 1 vars tengan alcance a partir de un valor pasado de una matriz (su valor a [i]), así que lo cambié a split..tmpLine [j]. También encontré que la variable 'i' de la sección END se mantuvo en el alcance en la función reverse, por lo que cambié eso a j para desambiguar la situación.


Tuve que encontrar algunas cosas, así que debajo está la versión de depuración que utilicé.

Si va a tener acceso a gawk, entonces hará bien en aprender a usar el depurador que está disponible. Si está utilizando awk/gawk/nawk en sistemas sin un depurador, este es un método para comprender lo que está sucediendo en su código. Si está redirigiendo la salida de los programas en un archivo o una tubería, y si el sistema es compatible con "/ dev/stderr" notación, podría imprimir las líneas de depuración allí, es decir,

#dbg print "#dbg0:line=" line > "/dev/stderr" 

Algunos sistemas tienen otras notaciones para acceder stderr, así que si vas a hacer tanto, vale la pena averiguar qué hay disponible.

cat commandFile.debug 
function reverse(line) { 
    n=split(line, tmpLine) 
    #dbg print "#dbg0:line=" line 
    #dbg print "#dbg1:n=" n "\tj=" j "\ttmpLine[j]=" tmpLine[j] 
    for (j=n; j>0; j--) { 
    #dbg print "#dbg2:n=" n "\tj=" j "\ttempLine[j]=" tmpLine[j] 
    printf("%s ",tmpLine[j]) 
    } 

} 
# main loop 
{ a[NR]=$0 } 

# print reversed array 
#dbg END{ print "AT END"; for(i=NR; i>0; i--) printf("#dbg4:i=%d\t%s\n%s\n", i, a[i] , reverse(a[i]) 
) } 
END{ for(i=NR; i>0; i--) printf("%s\n", reverse(a[i])) } 

Espero que esto ayude.

2
awk ' 
{ 
    x=reverse($0) (x?"\n":"") x 
} 

END{ 
    print x 
} 

function reverse(s, p) 
{ 
    for(i=length(s);i>0;i--) 
     p=p substr(s,i,1) 
    return p 
}' File1 
2

uso tac para revertir las líneas del archivo, a continuación, awk para revertir las palabras.

tac filename | awk '{for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)}' 

También podría usar algo como Perl que tiene funciones de lista de reversión incorporadas:

tac filename | perl -lane 'print join(" ", reverse(@F))' 
Cuestiones relacionadas