reordenar columnas con AWK

I need to reorder the columns of this (tab-separated) data:

   1 cat    plays
   1 dog    eats
   1 horse  runs
   1 red    dog
   1 the    cat
   1 the    cat

so that is prints like:

cat plays   1
dog eats    1
horse   runs    1
red dog 1
the cat 2

Yo he tratado:

sort [input] | uniq -c | awk '{print $2 "\t" $3 "\t" $1}' > [output]

y el resultado es:

1   cat 1
1   dog 1
1   horse   1
1   red 1
2   the 1

Can anyone give me some insight on what is going wrong? Thank you.

preguntado el 22 de septiembre de 13 a las 18:09

Others have answered your question. As a matter of style, I'd write awk -v OFS='\t' '{print $3, $4, $1}' -

4 Respuestas

Dado que la salida de cat input | sort | uniq -c es:

   1    1 cat    plays
   1    1 dog    eats
   1    1 horse  runs
   1    1 red    dog
   2    1 the    cat

necesitas algo como:

cat input | sort | uniq -c | awk '{print $3 "\t" $4 "\t" $1}'

And we can also indicate the output field separator in awk:

cat input | sort | uniq -c | awk -v OFS="\t" '{print $3,$4,$1}'

Respondido 04 ago 20, 22:08

Note that if you have spaces in your values, awk will split on them. To avoid that, and restrict separators to tabs only, pass this extra argument: awk -F $'\t' ... - Mathieu Rey

uniq -c adds an extra column. This should give you the output you want:

$ sort file | uniq -c | awk '{print $3 "\t" $4 "\t" $1}'
cat     plays   1
dog     eats    1
horse   runs    1
red     dog     1
the     cat     2

Respondido el 22 de Septiembre de 13 a las 18:09

Con awk y sort:

$ awk '{a[$2 OFS $3]++}END{for(k in a)print k,a[k]}' OFS='\t' file | sort -nk3 
cat     plays   1
dog     eats    1
horse   runs    1
red     dog     1
the     cat     2

Respondido el 22 de Septiembre de 13 a las 18:09

If you have GNU awk (gawk), you could use only it and its feature function asorti():

#!/usr/bin/env gawk -f
{
    a[$2 "\t" $3]++
}
END {
    asorti(a, b)
    for (i = 1; i in b; ++i) print b[i] "\t" a[b[i]]
}

Una línea:

gawk '{++a[$2"\t"$3]}END{asorti(a,b);for(i=1;i in b;++i)print b[i]"\t"a[b[i]]}' file

Salida:

cat plays   1
dog eats    1
horse   runs    1
red dog 1
the cat 2

UPDATE: To preserve original order without sorting use:

#!/usr/bin/awk -f
!a[$2 "\t" $3]++ {
    b[++i] = $2 "\t" $3
}
END {
    for (j = 1; j <= i; ++j) print b[j] "\t" a[b[j]]
}

Or

awk '!a[$2"\t"$3]++{b[++i]=$2"\t"$3}END{for(j=1;j<=i;++j)print b[j]"\t"a[b[j]]}' file

Any awk version would be compatible with that this time.

Output should be the same this time since input is already sorted by default.

Respondido el 22 de Septiembre de 13 a las 19:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.