Wie gruppiere ich Zeilen in einer Datei nach zwei?

9

Ich habe eine Textdatei wie diese:

a
b
c
d
e
f
g

Wie kann ich diese Zeilen gruppieren, um eine Ausgabe wie folgt zu erhalten:

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

Ich muss das in Shell machen (sh, csh, bash).

Ich habe folgendes gefunden:

cat file | xargs -n2

aber das letzte Element der ersten Gruppe wird nicht das erste der zweiten.

Costel Balta-Coman
quelle

Antworten:

9

Mit awk:

awk 'NR!=1{print x"-"$0}{x=$0}' file
  • NR!=1 gilt für alle Zeilen außer der ersten
  • print x"-"$0 Drucken Sie die Werte mit einem Bindestrich zwischen
  • x=$0set x(für die nächste Iteration)
Chaos
quelle
5

Mit POSIX sed:

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

oder einzeilige Version:

sed -e '1{h;d' -e\} -e 'H;x;s/\n/-/' <file
cuonglm
quelle
Ich brauche den ersten Buchstaben der zweiten Zeile, um der letzte in der ersten Zeile zu sein ...
Costel Balta-Coman
Gute Nutzung des Laderaums.
Wildcard
Ja, es ist in Ordnung.
Mikeserv
Können Sie erklären, wie das funktioniert?
Yossarian
5
paste -d- - ./infile <infile

^ Das würde wirklich gut funktionieren, außer dass Ihre Eingabe einzeln erfolgt. So...

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

... würde funktionieren, ist aber vielleicht zu kompliziert ...

mikeserv
quelle
Nun, genau das kam mir zuerst in den Sinn, nachdem ich die OP-Anforderung falsch gelesen hatte, aber ich beschloss, sedes in Ruhe zu lassen .
Cuonglm
@ Cuonglm - habe ich es falsch verstanden?
Mikeserv
1
Nein, ich wette. Aber du musst sed 1d\;\$des korrigieren.
Cuonglm
Wie wäre es mit dieser Variante? sed '2~2p' infile | paste -d- - -
Steeldriver
1
Jetzt sehe ich. paste -d- <(head -n -1 input) <(tail -n +2 input)
Costas
2

Einer noch sed

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

und kann geändert werden (dank mikeserv ):

sed -n 'N;y/\n/-/;P;y/-/\n/;D' <input
Costas
quelle
1
y/-\n/\n-/könnte vielleicht beide s /// ersetzen. In diesem Fall wäre es schneller, tragbar und kürzer.
Mikeserv
1

Eine reine Bash-Version -

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
quelle