awk sem imprimir nova linha

169

Quero que a variável sum / NR seja impressa lado a lado em cada iteração. Como evitar que o awk imprima uma nova linha em cada iteração? No meu código, uma nova linha é impressa por padrão em cada iteração

for file in cg_c ep_c is_c tau xhpl
printf "\n $file" >> to-plot.xls
    for f in 2.54 1.60 800 
        awk '{sum+=$3}; END  {print  sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
    done
done

Eu quero que a saída apareça assim

cg_c ans1  ans2  ans3  
ep_c ans1  ans2  ans3 
is_c ans1  ans2  ans3
tau  ans1  ans2  ans3 
xhpl ans1  ans2  ans3

minha saída atual é assim

**cg_c**
ans1
ans2
ans3
**ep_c**
ans1
ans2
ans3
**is_c**
ans1
ans2
ans3
**tau**
ans1
ans2
ans3
**xhpl**
ans1
ans2
ans3
Sharat Chandra
fonte

Respostas:

220

awk '{sum+=$3}; END {printf "%f",sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls

printirá inserir uma nova linha por padrão. Você não quer que isso aconteça; portanto, use-o printf.

CodeRain
fonte
4
Mas lembre-se de que os printfinterpreta %sassim usam em printf "%s" whatevervez de printf whatever.
Matthieu
1
printf "%s",whateverVocê esqueceu a vírgula. Você também pode estender com mais variáveis ​​e separá-las com uma vírgula.
Hielke Walinga
74

A variável ORS (separador de registros de saída) no AWK é padronizada como "\ n" e é impressa após cada linha. Você pode alterá-lo para "" na BEGINseção se desejar que tudo seja impresso consecutivamente.

danben
fonte
6
Você pode até querer configurá-lo ""(sem espaço) para não ter nenhuma separação.
mschilli
8
Assim:awk 'BEGIN {ORS="\t"} {sum+=$3}; END {print sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
Fredrik Erlandsson
2
Ou ORS="\r"se você quiser, por exemplo, imprimir um contador mostrando a progressão.
Skippy le Grand Gourou
47

Eu acho que muitas pessoas estão entrando nessa questão procurando uma maneira de evitar a nova linha awk. Assim, vou oferecer uma solução para isso, já que a resposta para o contexto específico já foi resolvida!

Em awk, printinsere automaticamente um ORSapós a impressão. ORSsignifica "separador de registro de saída" e o padrão é a nova linha. Então, sempre que você dizprint "hi" awk, imprime "oi" + nova linha.

Isso pode ser alterado de duas maneiras diferentes: usando um vazio ORSou usando printf.

Usando um vazio ORS

awk -v ORS= '1' <<< "hello
man"

Isso retorna "helloman", todos juntos.

O problema aqui é que nem todos os awks aceitam definir um vazio ORS, então você provavelmente precisará definir outro separador de registros.

awk -v ORS="-" '{print ...}' file

Por exemplo:

awk -v ORS="-" '1' <<< "hello
man"

Retorna "olá-homem-".

Usando printf(preferível)

Enquanto printanexa ORSapós o registro, printfnão. Assim, printf "hello"apenas imprime "olá", nada mais.

$ awk 'BEGIN{print "hello"; print "bye"}'
hello
bye
$ awk 'BEGIN{printf "hello"; printf "bye"}'
hellobye

Por fim, observe que, em geral, isso perde uma nova linha final, para que o prompt do shell fique na mesma linha que a última linha da saída. Para limpar isso, use END {print ""}para que uma nova linha seja impressa após todo o processamento.

$ seq 5 | awk '{printf "%s", $0}'
12345$
#    ^ prompt here

$ seq 5 | awk '{printf "%s", $0} END {print ""}'
12345
fedorqui 'Então pare de prejudicar'
fonte
5

mão única

awk '/^\*\*/{gsub("*","");printf "\n"$0" ";next}{printf $0" "}' to-plot.xls
ghostdog74
fonte
1
Pequena nota: nunca use printf $0, uma vez que $0podem conter strings como %F, etc ... A seguir facilmente falhar (pelo menos com GAWK 3.1.5): echo "%F"|awk '{printf $0}'. Use o printf "%s",$0lugar.
Vlad
2

Você pode simplesmente usar o ORS dinamicamente assim:

awk '{ORS="" ; print($1" "$2" "$3" "$4" "$5" "); ORS="\n"; print($6-=2*$6)}' file_in > file_out

Andrea Barletta
fonte
1

Se Perl é uma opção, aqui está uma solução usando o exemplo de fedorqui:

seq 5 | perl -ne 'chomp; print "$_ "; END{print "\n"}'

Explicação:
chompremove a nova linha
print "$_ "imprime cada linha, acrescentando um espaço em que
o END{}bloco é usado para imprimir uma nova linha

resultado: 1 2 3 4 5

Chris Koknat
fonte