Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a text file like this:

a
b
c
d
e
f
g

How can I group those lines to obtain an output like this:

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

I have to do this in shell (sh, csh, bash).

I have found this:

cat file | xargs -n2

but the last element of first group does not became the first of the second.

share|improve this question
up vote 9 down vote accepted

With awk:

awk 'NR!=1{print x"-"$0}{x=$0}' file
  • NR!=1 applies on all line, except the first one
  • print x"-"$0 print the values with dash between
  • x=$0 set x (for the next iteration)
share|improve this answer

With POSIX sed:

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

or one-liner version:

sed -e '1{h;d' -e\} -e 'H;x;s/\n/-/' <file
share|improve this answer
    
I need the first letter of the second line to be the last in the first line... – Costel Balta-Coman Jan 26 at 16:01
    
Nice use of the hold space. – Wildcard Jan 26 at 16:49
    
yeah, its fine. – mikeserv Jan 26 at 17:52
    
Could you explain how this works? – Yossarian Jan 27 at 11:54
paste -d- - ./infile <infile

^That would work really well, except that your input is off-by-one. So...

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

...would work, but maybe is too complicated...

share|improve this answer
    
Well, that's exactly the same came into my mind at first after mis-reading the OP requirement, but I decided to let sed do it alone. – cuonglm Jan 26 at 17:24
    
@cuonglm - did i misread it? – mikeserv Jan 26 at 17:25
1  
No, I bet. But you need sed 1d\;\$d to correct it. – cuonglm Jan 26 at 17:28
    
@cuonglm - on the money. thanks, cuonglm – mikeserv Jan 26 at 17:29
1  
Now I see. paste -d- <(head -n -1 input) <(tail -n +2 input) – Costas Jan 26 at 19:51

One more sed

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

and can be modified (thanks to mikeserv):

sed -n 'N;y/\n/-/;P;y/-/\n/;D' <input
share|improve this answer
1  
y/-\n/\n-/ could replace both s/// maybe. If it did it would be quicker, portable for the \n use, and shorter. – mikeserv Jan 26 at 19:49

A pure 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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.