bash / sed / awk / etc hapus setiap baris baru lainnya

39

a bash perintah menampilkan ini:

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

Saya ingin menyalurkannya ke sesuatu agar terlihat seperti ini:

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
[...]

yaitu menghapus setiap baris baru lainnya

Saya mencoba ... |tr "\nGroup" " "tetapi menghapus semua baris baru dan memakan beberapa surat lainnya juga. Terima kasih

carillonator
sumber
2
trsepenuhnya berdasarkan karakter: Anda meminta tr untuk menghapus baris baru dan semua 'G', 'r', 'o', 'u', dan 'p'.
glenn jackman

Jawaban:

80

tidak dapat menguji sekarang, tetapi

... | paste - - 

harus melakukannya

glenn jackman
sumber
5
+1 - berfungsi dan elegan. (Ini menempatkan tab di antara garis - paste -d ' ' - -akan menambah ruang sebagai gantinya jika diperlukan)
cyberx86
4
Bisakah Anda jelaskan bagaimana cara kerjanya? Kenapa ada dua -? Terima kasih
bbaja42
7
pastedigunakan untuk menggabungkan baris-baris dari file: paste file1 file2 file3 .... Jika salah satu dari argumen "file" adalah "-", maka baris dibaca dari input standar. Jika ada 2 "-" argumen, maka tempel mengambil 2 baris dari stdin. Dan seterusnya. Lihat halaman manual .
glenn jackman
10

Satu kemungkinan adalah:

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

Jika nomor baris habis dibagi 2, akhiri dengan baris baru, jika tidak, akhiri dengan spasi.

(Diuji pada: CentOS 6, GNU Awk 3.1.7)

Menggunakan sed (lihat penjelasan ):

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

Bacaan lebih lanjut:

cyberx86
sumber
8

Jika ingin digunakan sed , tidak ada alasan untuk membaca seluruh file ke dalam memori. Anda dapat menggabungkan setiap baris lain seperti ini:

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

Gunakan karakter apa pun yang Anda suka sebagai ganti spasi.

Berikut cara lain menggunakan awk:

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

The if/elsemenangani kasus di mana ada ganjil baris dalam berkas. Tanpa itu, baris terakhir yang aneh akan dicetak dua kali. Kalau tidak, untuk perbandingan, Anda bisa melakukan:

awk '{printf "%s", $0; getline; print " " $0}'
Dijeda sampai pemberitahuan lebih lanjut.
sumber
1
Komentar telat: 1) selalu menggunakan penspesifikasi format untuk printf jika seandainya string memiliki tanda persen, 2) untuk menghindari duplikasi baris terakhir, set $ 0 ke "" -awk '{printf "%s", $0; $0=""; getline; print " " $0}'
glenn jackman
3

Cara paling idiomatis untuk melakukannya awkadalah sebagai berikut:

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

Ini menghasilkan:

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

Untuk menjelaskannya, kita perlu mendefinisikan masing-masing variabel bawaan:

  • RSpemisah rekaman. Default ke\n (baris baru).
  • ORSpemisah catatan keluaran. Default ke\n (baris baru).
  • FSpemisah bidang. Default ke (spasi).
  • NR jumlah catatan.

Karena pemisah rekaman default adalah baris baru, catatan adalah, sebagai default, sebuah baris.

NR%2adalah modulus dari NR/2, sehingga akan menjadi salah satu 0atau 1. 0untuk garis genap dan1 garis ganjil.

var=condition?condition_if_true:condition_if_false adalah operator ternary.

Secara keseluruhan, mengatakan ORS=NR%2?FS:RSkita mendefinisikan pemisah catatan output:

  • jika jumlah catatan ada di formulir 2k + 1 , yaitu, pada garis genap, maka pemisah rekaman keluaran diatur ke FS, yaitu, spasi.
  • jika jumlah catatan ada di formulir 2k, yaitu, pada garis ganjil, maka pemisah rekaman keluaran diatur keRS , yaitu, baris baru.

Dengan cara ini, garis ganjil diakhiri dengan spasi, yang kemudian bergabung dengan baris berikutnya. Setelah baris itu, baris baru dicetak.

Info lebih lanjut di idiomatic awk .

fedorqui
sumber
2

Ini berfungsi untuk saya di Linux:

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

Ini menggantikan ruang kosong untuk karakter baris baru; Anda harus keluar dari karakter baris baru agar sesuatu berfungsi dengan benar.

Bret McMillan
sumber
Ini menghapus setiap baris baru, bukan setiap baris baru lainnya .
Trenton
2

Dalam bash:

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

Jika Perl adalah opsi:

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

s/\n/ /menggantikan baris baru dengan spasi
$.adalah nomor baris

Chris Koknat
sumber
-1

Bagaimana kalau menggunakan grep?

.. | grep -v '^Group State'
pkhamre
sumber
Itu menghilangkan garis alternatif. OP ingin mereka ditambahkan.
Dijeda sampai pemberitahuan lebih lanjut.
Ya, setelah membaca kembali pertanyaan saya baru menyadari bahwa :)
pkhamre