1

This question already has an answer here:

I am stuck on this.

i have an input file that looks like

16:20:03 Buy
DRIP
AMEX
500 13,51 USD
16:05:10 Sell
SQ
NYSE
100 36,32 USD
15:48:52 Sell
NXTD
Nasdaq
500 4,99 USD
15:48:52 Sell
NXTD
Nasdaq
500 4,99 USD
15:46:07 Buy
SOXL
AMEX
50 147,7209 USD
15:40:20 Buy
TEUM
AMEX
1 700 1,36 USD
15:40:19 Buy
TEUM
AMEX
300 1,36 USD

my goal is to get each four-line record onto one line, e.g.

16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD

I know that each record is four lines. i also know that each record starts with (is separated by) a time on format hh:mm:ss

I have tried various awk commands specifying RS/FS OFS/ORS I have tried different variants of sed like

sed 'N;N;s/\n/ /'

The awk prints first record only. The sed doesn't manage to get all elements on same line

I can post more specific examples of what i have tried. It looks reallly simply. anyone who can give me a hint?

If you know an easier solution in another language, feel free to elaborate

marked as duplicate by don_crissti, Stephen Rauch, Sparhawk, John, G-Man Dec 22 '17 at 2:50

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • or Club together N consecutive line etc... plenty of similar questions... – don_crissti Dec 21 '17 at 22:40
  • Thanks for all the great answers, it looks like my problem was related to DOS Line breaks in the file. sorry for the post. – HenrikJson Dec 22 '17 at 8:17
4

Using paste

$ paste -d' ' - - - - <file
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD

Using sed

$ sed 'N;N;N; s/\n/ /g' file
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD

Using awk

$ awk '{line=line " " $0} NR%4==0{print substr(line,2); line=""}' file
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD
3

Perl solution

perl -pe 's/\n/ / if $. % 4' < file
  • -p reads the input line by line, processes it and prints it back to the output;
  • $. contains the input line number
  • s/\n/ / replaces a newline by a space
  • % is the modulo operator, so the condition reads "if the line number isn't divisible by four"
1

The easiest solution is probably with ex, the non-visual form of vi (which is specified by POSIX).

printf '%s\n' 'g/^/j4' x | ex input.txt

Equivalently:

printf 'g/^/j4\nx\n' | ex input.txt

Explanation:

The printf command just produces the following output, which are commands to ex:

g/^/j4
x

The x command means to save and exit. Replace with %p if you want to print the modified file to standard output and not save changes (good for testing).

g is the global command and takes a regex (in this case /^/ which will of course match on every line) and then a command. The command is run on every line matched by the regex.

j4 means to join the current line with the following three lines. Spaces are put in between when joining.


You can also fire up vi and just type 4J and then j to go down a line and then type ., and then j to go down a line and then ., etc. But with the ex form any left-over lines at the end of the file (less than four) will be joined together; with the J command in vi this is not the case.

0
$ awk '{printf $0 (NR%4?" ":"\n")}' file1
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD

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