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.

Costel Balta-Coman
sumber

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)
kekacauan
sumber
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
cuonglm
sumber
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 ...

mikeserv
sumber
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
Costas
sumber
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
jai_s
sumber