awk โดยไม่ต้องพิมพ์ newline


169

ฉันต้องการผลรวมตัวแปร / NR ที่จะพิมพ์แบบเคียงข้างกันในการทำซ้ำแต่ละครั้ง เราจะหลีกเลี่ยง awk จากการพิมพ์บรรทัดใหม่ในแต่ละการวนซ้ำได้อย่างไร ในรหัสของฉันบรรทัดใหม่จะถูกพิมพ์ตามค่าเริ่มต้นในการทำซ้ำแต่ละครั้ง

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

ฉันต้องการให้ผลลัพธ์ปรากฏเช่นนี้

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

สิ่งที่ฉันเลือกในปัจจุบันเป็นเช่นนี้

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

คำตอบ:


219

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

printจะแทรกขึ้นบรรทัดใหม่ตามค่าเริ่มต้น คุณไม่ต้องการที่จะเกิดขึ้นจึงใช้printfแทน


4
แต่ทราบว่าprintfตีความ%sเพื่อใช้แทนprintf "%s" whatever printf whatever
Matthieu

1
printf "%s",whateverคุณลืมเครื่องหมายจุลภาค นอกจากนี้คุณยังสามารถขยายตัวแปรเพิ่มเติมและแยกพวกเขาด้วยเครื่องหมายจุลภาค
Hielke Walinga

74

ตัวแปร ORS (ตัวแยกเร็กคอร์ดออก) ใน AWK ค่าเริ่มต้นเป็น "\ n" และพิมพ์หลังจากทุกบรรทัด คุณสามารถเปลี่ยนเป็น "" ในBEGINส่วนหากคุณต้องการพิมพ์ทุกอย่างอย่างต่อเนื่อง


6
คุณอาจต้องการตั้งค่า""(ไม่มีที่ว่าง) เพื่อไม่มีการแยกเลย
mschilli

8
เช่นนี้:awk 'BEGIN {ORS="\t"} {sum+=$3}; END {print sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
Fredrik Erlandsson

2
หรือORS="\r"ถ้าคุณต้องการเช่นพิมพ์เคาน์เตอร์แสดงความก้าวหน้า
Skippy le Grand Gourou

47

ผมคิดว่าหลาย ๆ awkคนที่กำลังเข้าสู่ในคำถามนี้มองหาวิธีที่จะหลีกเลี่ยงการขึ้นบรรทัดใหม่ใน ดังนั้นฉันจะเสนอวิธีแก้ปัญหาแบบนั้นเนื่องจากคำตอบของบริบทเฉพาะได้รับการแก้ไขแล้ว!

ในawk,printแทรกโดยอัตโนมัติORSหลังจากการพิมพ์ ORSย่อมาจาก "ตัวแยกบันทึกเอาท์พุท" และใช้ค่าเริ่มต้นไปที่บรรทัดใหม่ ดังนั้นเมื่อใดก็ตามที่คุณบอกว่าprint "hi"awk พิมพ์ "hi" + ขึ้นบรรทัดใหม่

สิ่งนี้สามารถเปลี่ยนแปลงได้สองวิธี: การใช้ช่องว่าง ORSprintfหรือใช้

ใช้เปล่า ORS

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

สิ่งนี้จะส่งกลับ "helloman" ทั้งหมดเข้าด้วยกัน

ปัญหาที่นี่คือไม่ใช่ทุก awks ยอมรับการตั้งค่าที่ว่างเปล่าORSดังนั้นคุณอาจต้องตั้งค่าตัวแยกระเบียนอื่น

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

ตัวอย่างเช่น:

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

ส่งคืน "hello-man-"

การใช้ printf (ดีกว่า)

ในขณะที่printแนบORSหลังจากบันทึกprintfไม่ได้ ดังนั้นprintf "hello"เพียงพิมพ์ "hello" ไม่มีอะไรอื่น

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

สุดท้ายโปรดทราบว่าโดยทั่วไปสิ่งนี้จะขาดบรรทัดใหม่สุดท้ายเพื่อให้เชลล์พรอมต์จะอยู่ในบรรทัดเดียวกันกับบรรทัดสุดท้ายของเอาต์พุต ในการทำความสะอาดให้ใช้END {print ""}บรรทัดใหม่ที่จะพิมพ์หลังจากการประมวลผลทั้งหมด

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

$ seq 5 | awk '{printf "%s", $0} END {print ""}'
12345

5

ทางเดียว

awk '/^\*\*/{gsub("*","");printf "\n"$0" ";next}{printf $0" "}' to-plot.xls

1
บันทึกไมเนอร์: ไม่เคยใช้printf $0เนื่องจาก$0อาจมีสายเหมือน%Fฯลฯ ... ต่อไปนี้ได้อย่างง่ายดายล้มเหลว (อย่างน้อยกับเพ่งพิศ echo "%F"|awk '{printf $0}'3.1.5): ใช้printf "%s",$0แทน
ว.

2

คุณสามารถใช้ ORS แบบไดนามิกดังนี้:

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


1

ถ้า Perl เป็นตัวเลือกต่อไปนี้เป็นวิธีการแก้ปัญหาโดยใช้ตัวอย่างของ fedorqui:

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

คำอธิบาย:
chompเอาการขึ้นบรรทัดใหม่
print "$_ "พิมพ์แต่ละบรรทัดท้ายพื้นที่
END{}บล็อกใช้เพื่อพิมพ์บรรทัดใหม่

เอาท์พุท: 1 2 3 4 5

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.