bash / sed / awk / etc xóa mọi dòng mới khác


39

một lệnh bash xuất ra điều này:

Runtime Name: vmhba2:C0:T3:L14
Group State: active
Runtime Name: vmhba3:C0:T0:L14
Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14
Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14
Group State: active
Runtime Name: vmhba2:C0:T2:L14
Group State: active

Tôi muốn chuyển nó sang một cái gì đó để làm cho nó trông như thế này:

Runtime Name: vmhba2:C0:T1:L14 Group State: active 
Runtime Name: vmhba3:C0:T3:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T2:L14 Group State: active
[...]

tức là xóa mọi dòng mới

Tôi đã thử ... |tr "\nGroup" " "nhưng nó cũng loại bỏ tất cả các dòng mới và ăn một số chữ cái khác. cảm ơn


2
trhoàn toàn dựa trên ký tự: bạn đã yêu cầu tr xóa các dòng mới và tất cả 'G', 'r', 'o', 'u' và 'p'.
glenn jackman

Câu trả lời:


80

không thể kiểm tra ngay bây giờ, nhưng

... | paste - - 

Hãy làm nó


5
+1 - hoạt động và thanh lịch. (Nó đặt một tab giữa các dòng - paste -d ' ' - -thay vào đó sẽ thêm một khoảng
trắng

4
Bạn có thể vui lòng giải thích làm thế nào để lệnh làm việc? Tại sao có hai -? Cảm ơn
bbaja42

7
pasteđược sử dụng để nối các dòng tương ứng từ các tệp : paste file1 file2 file3 .... Nếu một trong các đối số "tệp" là "-", thì các dòng được đọc từ đầu vào tiêu chuẩn. Nếu có 2 đối số "-", thì dán sẽ lấy 2 dòng từ stdin. Và như vậy. Xem trang người đàn ông .
glenn jackman

10

Một khả năng là:

awk 'ORS=NR%2?" ":"\n"'

Nếu số dòng chia hết cho 2, kết thúc bằng một dòng mới, nếu không, kết thúc bằng một khoảng trắng.

(Đã thử nghiệm trên: CentOS 6, GNU Awk 3.1.7)

Sử dụng sed (xem giải thích ):

sed ':a;N;$!ba;s/\nGroup/ Group/g'

Đọc thêm:


8

Nếu bạn muốn sử dụng sed, không có lý do gì để đọc toàn bộ tệp vào bộ nhớ. Bạn có thể hợp nhất mọi dòng khác như thế này:

sed 'N;s/\n/ /' inputfile

Sử dụng bất kỳ nhân vật nào bạn thích thay vì khoảng trắng.

Đây là một cách khác sử dụng awk:

awk '{printf "%s", $0; if (getline) print " " $0; else printf "\n"}' inputfile

Việc if/elsexử lý trường hợp có một số dòng lẻ trong tệp. Không có nó, dòng cuối cùng lẻ được in hai lần. Nếu không, để so sánh, bạn có thể làm:

awk '{printf "%s", $0; getline; print " " $0}'

1
Nhận xét muộn: 1) luôn sử dụng công cụ xác định định dạng cho printf trong trường hợp chuỗi có dấu phần trăm, 2) để tránh dòng cuối trùng lặp, đặt $ 0 thành "" -awk '{printf "%s", $0; $0=""; getline; print " " $0}'
glenn jackman

3

Cách thành ngữ nhất để làm điều đó awklà như sau:

awk 'ORS=NR%2?FS:RS' file

Nó xuất ra:

Runtime Name: vmhba2:C0:T3:L14 Group State: active
Runtime Name: vmhba3:C0:T0:L14 Group State: active unoptimized
Runtime Name: vmhba2:C0:T1:L14 Group State: active unoptimized
Runtime Name: vmhba3:C0:T3:L14 Group State: active
Runtime Name: vmhba2:C0:T2:L14 Group State: active

Để giải thích nó, chúng ta cần xác định từng biến tích hợp:

  • RStách hồ sơ. Mặc định cho \n(dòng mới).
  • ORSphân tách hồ sơ đầu ra. Mặc định cho \n(dòng mới).
  • FSdải phân cách. Mặc định cho (không gian).
  • NR số lượng hồ sơ.

Vì dấu tách bản ghi mặc định là dòng mới, bản ghi là mặc định là dòng.

NR%2là mô-đun của NR/2, do đó nó sẽ là 0hoặc 1. 0cho các dòng chẵn và 1cho các dòng lẻ.

var=condition?condition_if_true:condition_if_false là toán tử ternary.

Tất cả cùng nhau, nói rằng ORS=NR%2?FS:RSchúng tôi đang xác định phân tách bản ghi đầu ra:

  • nếu số lượng bản ghi trên biểu mẫu 2k + 1, nghĩa là trên các dòng chẵn, thì các dấu tách bản ghi đầu ra được đặt thành FS, đó là một khoảng trắng.
  • nếu số lượng bản ghi trên biểu mẫu 2k, nghĩa là trên các dòng lẻ, thì các dấu tách bản ghi đầu ra được đặt thành RS, đó là một dòng mới.

Bằng cách này, các dòng lẻ kết thúc bằng một khoảng trắng, sau đó được nối với dòng tiếp theo. Sau dòng đó, một dòng mới được in.

Thêm thông tin trong Thành ngữ awk .


2

Điều này làm việc cho tôi trên Linux:

... | tr "\\n" " "

Điều này thay thế một không gian trống cho một nhân vật dòng mới; bạn phải thoát khỏi ký tự dòng mới để mọi thứ hoạt động chính xác.


Điều này loại bỏ mọi dòng mới, không phải mọi dòng mới khác .
Trenton

2

Trong bash:

... | while read l1; do read l2; echo "$l1 $l2"; done

1

Nếu Perl là một tùy chọn:

perl -pe 's/\n/ / if $. % 2 == 1' file

s/\n/ /thay thế dòng mới bằng dấu cách
$.là số dòng


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.