awk sans impression de nouvelle ligne

169

Je veux que la variable sum / NR soit imprimée côte à côte à chaque itération. Comment éviter que awk n'imprime une nouvelle ligne à chaque itération? Dans mon code, une nouvelle ligne est imprimée par défaut à chaque itération

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

Je veux que la sortie apparaisse comme ceci

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

ma sortie actuelle est comme ça

**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
la source

Réponses:

220

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

printinsérera une nouvelle ligne par défaut. Vous ne voulez pas que cela se produise, utilisez donc à la printfplace.

CodeRain
la source
4
Mais l'esprit qui printfinterprète %sdonc utiliser printf "%s" whateverau lieu de printf whatever.
Matthieu
1
printf "%s",whateverVous avez oublié la virgule. Vous pouvez également étendre avec plus de variables et les séparer par une virgule.
Hielke Walinga
74

La variable ORS (séparateur d'enregistrement de sortie) dans AWK est par défaut "\ n" et est imprimée après chaque ligne. Vous pouvez le changer en "" dans la BEGINsection si vous voulez que tout soit imprimé consécutivement.

Danben
la source
6
Vous voudrez peut-être même le définir ""(sans espace) pour qu'il n'ait aucune séparation.
mschilli
8
Comme ça:awk 'BEGIN {ORS="\t"} {sum+=$3}; END {print sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
Fredrik Erlandsson
2
Ou ORS="\r"si vous voulez par exemple imprimer un compteur montrant la progression.
Skippy le Grand Gourou
47

Je suppose que beaucoup de gens entrent dans cette question à la recherche d'un moyen d'éviter la nouvelle ligne awk. Ainsi, je vais proposer une solution à cela, puisque la réponse au contexte spécifique était déjà résolue!

Dans awk, printinsère automatiquement un ORSaprès l'impression. ORSsignifie "séparateur d'enregistrements de sortie" et utilise par défaut la nouvelle ligne. Ainsi, chaque fois que vous dites print "hi"awk imprime "hi" + nouvelle ligne.

Cela peut être modifié de deux manières différentes: en utilisant un fichier vide ORSou en utilisant printf.

Utiliser un vide ORS

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

Cela renvoie "helloman", tous ensemble.

Le problème ici est que tous les awks n'acceptent pas de définir un vide ORS, vous devez donc probablement définir un autre séparateur d'enregistrement.

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

Par exemple:

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

Renvoie "hello-man-".

Utilisation printf(préférable)

Bien que printjoint ORSaprès l'enregistrement, printfne le fait pas. Ainsi, printf "hello"imprime simplement "bonjour", rien d'autre.

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

Enfin, notez qu'en général, cela manque une nouvelle ligne finale, de sorte que l'invite du shell sera dans la même ligne que la dernière ligne de la sortie. Pour nettoyer cela, utilisez END {print ""}pour qu'une nouvelle ligne soit imprimée après tout le traitement.

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

$ seq 5 | awk '{printf "%s", $0} END {print ""}'
12345
fedorqui 'Alors arrêtez de nuire'
la source
5

une manière

awk '/^\*\*/{gsub("*","");printf "\n"$0" ";next}{printf $0" "}' to-plot.xls
ghostdog74
la source
1
Note mineure: ne jamais utiliser printf $0, car $0peut contenir des chaînes comme %F, etc ... A la suite échoue facilement (au moins avec GAWK 3.1.5): echo "%F"|awk '{printf $0}'. Utilisez printf "%s",$0plutôt le.
Vlad
2

Vous pouvez simplement utiliser ORS dynamiquement comme ceci:

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

Andrea Barletta
la source
1

Si Perl est une option, voici une solution utilisant l'exemple de fedorqui:

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

Explication:
chompsupprime la nouvelle ligne
print "$_ "imprime chaque ligne, en ajoutant un espace
le END{}bloc est utilisé pour imprimer une nouvelle ligne

production: 1 2 3 4 5

Chris Koknat
la source