Bagaimana cara mengelompokkan baris dalam file dengan dua?


9

Saya memiliki file teks seperti ini:

a
b
c
d
e
f
g

Bagaimana saya bisa mengelompokkan garis-garis itu untuk mendapatkan output seperti ini:

a-b
b-c
c-d
d-e
e-f
f-g

Saya harus melakukan ini di shell (sh, csh, bash).

Saya telah menemukan ini:

cat file | xargs -n2

tetapi elemen terakhir dari kelompok pertama tidak menjadi yang pertama dari yang kedua.

Jawaban:


9

Dengan awk:

awk 'NR!=1{print x"-"$0}{x=$0}' file
  • NR!=1 berlaku di semua baris, kecuali yang pertama
  • print x"-"$0 cetak nilai dengan tanda hubung antara
  • x=$0set x(untuk iterasi berikutnya)

5

Dengan POSIX sed:

sed '1{
  h
  d
}
H
x
s/\n/-/
' <file

atau versi satu-liner:

sed -e '1{h;d' -e\} -e 'H;x;s/\n/-/' <file

Saya membutuhkan huruf pertama dari baris kedua untuk menjadi yang terakhir di baris pertama ...
Costel Balta-Coman

Penggunaan ruang palka yang bagus.
Wildcard

ya, tidak apa-apa.
mikeserv

Bisakah Anda menjelaskan cara kerjanya?
Yossarian

5
paste -d- - ./infile <infile

^ Itu akan bekerja dengan sangat baik, kecuali bahwa input Anda tidak aktif. Begitu...

{ echo; cat <infile; } | paste -d- - ./infile | sed '1d;$d'

... akan bekerja, tapi mungkin terlalu rumit ...


Ya, itu persis sama dengan yang saya pikirkan pada awalnya setelah salah membaca persyaratan OP, tetapi saya memutuskan untuk membiarkannya sedsendiri.
cuonglm

@cuonglm - apakah saya salah baca?
mikeserv

1
Tidak, saya bertaruh. Tetapi Anda harus sed 1d\;\$dmemperbaikinya.
cuonglm

Bagaimana dengan varian ini? sed '2~2p' infile | paste -d- - -
steeldriver

1
Sekarang saya mengerti. paste -d- <(head -n -1 input) <(tail -n +2 input)
Costas

2

Satu lagi sed

sed '$!N;s/\n/-/p;s/-/\n/;D' <input

dan dapat dimodifikasi (terima kasih kepada mikeserv ):

sed -n 'N;y/\n/-/;P;y/-/\n/;D' <input

1
y/-\n/\n-/bisa mengganti keduanya s /// mungkin. Jika itu dilakukan akan lebih cepat, portabel untuk penggunaan \ n, dan lebih pendek.
mikeserv

1

Versi bash murni -

old=""; while read -r line ; do [[ -n "$old" ]] && echo   $old-$line;   old=$line; done  < input

a-b
b-c
c-d
d-e
e-f
f-g
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.