Following terdon's advice, im adding an alternative approach using sed
, i mainly include it for completeness, however unlike the awk '{printf "%s,", $1}'
which aggregates whilst ommitting the newline, with sed
we are actively replacing the newlines, thus it would also fit in when we wanted to replace a different character. It is inefficient though.
The command in question is ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed ':a;N;s/\n/, /;ba'
The very cryptic sed
command :a;N;s/\n/, /;ba
is actually quite simple if taken apart.
sed
transforms the input in one single pass (opposed to i.e. ed
, however ed
usually isnt included by default).
The unmodified ssh command returns:
[me@hostname ~]$ ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D"
05
Debian-76-wheezy-64-minimal
a
s
d
f
d
05/04/16
If we add N;s/\n//
we get:
[me@hostname ~]$ ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed 'N;s/\n//'
05Debian-76-wheezy-64-minimal
as
df
d05/04/16
The N
appends the next input line into the pattern space, the following s/\n//
removes the newline in the pattern space. Thats why we get pairs of lines with removed newlines here.
Now if we want the full input to get sent into the pattern space, we need to loop with help of a label.
[me@hostname ~]$ ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed ':a;N;s/\n//;ba'
05Debian-76-wheezy-64-minimalasdfd05/04/16
With :a
we set a label, with ba
we unconditionally jump to the label a
.
So what sed ':a;N;s/\n//;ba'
does is:
- Define label
a
- Append next line to pattern space (
N
)
- Send pattern space through
s/\n//
- Jump back to
a
Once there is no new line for N
to append it quits to the end of the script.
To get it CS we just need to change the replacement:
[me@hostname ~]$ ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed ':a;N;s/\n/, /;ba'
05, Debian-76-wheezy-64-minimal, a, s, d, f, d, 05/04/16
This isnt very efficient, especially for bigger linecount, since the pattern space gets the line appended and sent trought our replacement command for every single line. Would be more efficient to replace before aggregation, but sed
can't do that.
This becomes very obvious if we print the pattern space after N
appended the next line (Just put a p
at the position to get the current pattern space printed).
In the following ouput, every 2 lines represetn the current pattern space (because the *newline is still included) - just before the replacement of the newline by s/\n//
:
[me@hostname] ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed ':a;N;p;s/\n/, /;ba'
05
Debian-76-wheezy-64-minimal
05, Debian-76-wheezy-64-minimal
a
05, Debian-76-wheezy-64-minimal, a
s
05, Debian-76-wheezy-64-minimal, a, s
d
05, Debian-76-wheezy-64-minimal, a, s, d
f
05, Debian-76-wheezy-64-minimal, a, s, d, f
d
05, Debian-76-wheezy-64-minimal, a, s, d, f, d
05/04/16
05, Debian-76-wheezy-64-minimal, a, s, d, f, d, 05/04/16