awk mà không in dòng mới


169

Tôi muốn tổng biến / NR được in cạnh nhau trong mỗi lần lặp. Làm thế nào để chúng ta tránh awk từ việc in dòng mới trong mỗi lần lặp? Trong mã của tôi, một dòng mới được in theo mặc định trong mỗi lần lặp

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

Tôi muốn đầu ra xuất hiện như thế này

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

hiện tại của tôi là như thế này

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

Câu trả lời:


219

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

printsẽ chèn một dòng mới theo mặc định. Bạn không muốn điều đó xảy ra, do đó sử dụng printfthay thế.


4
Nhưng nhớ rằng printfgiải thích %sđể sử dụng printf "%s" whateverthay vì printf whatever.
Matthieu

1
printf "%s",whateverBạn quên dấu phẩy. Bạn cũng có thể mở rộng với nhiều biến hơn và phân tách chúng bằng dấu phẩy.
Hielke Walinga

74

Biến ORS (dấu tách bản ghi đầu ra) trong AWK mặc định là "\ n" và được in sau mỗi dòng. Bạn có thể thay đổi nó thành "" trong BEGINphần nếu bạn muốn mọi thứ được in liên tiếp.


6
Bạn thậm chí có thể muốn đặt nó ""(không có không gian) để không có sự tách biệt nào cả.
mschilli

8
Như thế này:awk 'BEGIN {ORS="\t"} {sum+=$3}; END {print sum/NR}' ${file}_${f}_v1.xls >> to-plot-p.xls
Fredrik Erlandsson

2
Hoặc ORS="\r"nếu bạn muốn ví dụ để in một bộ đếm hiển thị tiến trình.
Skippy le Grand Gourou

47

Tôi đoán nhiều người đang tham gia vào câu hỏi này để tìm cách tránh dòng mới awk. Vì vậy, tôi sẽ đưa ra một giải pháp cho điều đó, vì câu trả lời cho bối cảnh cụ thể đã được giải quyết!

Trong awk, printtự động chèn một ORSsau khi in. ORSlà viết tắt của "dấu tách bản ghi đầu ra" và mặc định cho dòng mới. Vì vậy, bất cứ khi nào bạn nói print "hi"awk in "hi" + dòng mới.

Điều này có thể được thay đổi theo hai cách khác nhau: sử dụng trống ORShoặc sử dụng printf.

Sử dụng một sản phẩm nào ORS

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

Điều này trả về "helloman", tất cả cùng nhau.

Vấn đề ở đây là không phải tất cả các awks đều chấp nhận đặt trống ORS, vì vậy bạn có thể phải đặt một dấu tách bản ghi khác.

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

Ví dụ:

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

Trả về "xin chào-"

Sử dụng printf(tốt hơn)

Trong khi printđính kèm ORSsau khi ghi, printfkhông. Do đó, printf "hello"chỉ cần in "xin chào", không có gì khác.

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

Cuối cùng, lưu ý rằng nói chung, điều này bỏ lỡ một dòng mới cuối cùng, do đó dấu nhắc shell sẽ nằm cùng dòng với dòng cuối cùng của đầu ra. Để làm sạch điều này, sử dụng END {print ""}để một dòng mới sẽ được in sau khi xử lý.

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

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

5

một chiều

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

1
Lưu ý nhỏ: không bao giờ sử dụng printf $0, vì $0có thể chứa các chuỗi như %F, v.v ... Theo sau dễ dàng thất bại (ít nhất là với GAWK 3.1.5) : echo "%F"|awk '{printf $0}'. Sử dụng printf "%s",$0thay thế.
Vlad

2

Bạn chỉ có thể sử dụng ORS một cách linh hoạt như thế này:

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


1

Nếu Perl là một tùy chọn, thì đây là một giải pháp sử dụng ví dụ của fedorqui's:

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

Giải thích:
chompxóa dòng
print "$_ "in mới từng dòng, nối thêm khoảng trắng
END{}khối được sử dụng để in dòng mới

đầu ra: 1 2 3 4 5

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.