Kalam
Kalam

Reputation: 45

How to append last column of every other row with the last column of the subsequent row

I'd like to append every other (odd-numbered rows) row with the last column of the subsequent row (even-numbered rows). I've tried several different commands but none seem to do the task I'm trying to achieve.

Raw data:

user|396012_232|program|30720Mn|
|396012_232.batch|batch|30720Mn|5108656K
user|398498_2|program|102400Mn|
|398498_2.batch|batch|102400Mn|36426336K
user|391983_233|program|30720Mn|
|391983_233.batch|batch|30720Mn|5050424K

I'd like to take the last field in the "batch" lines and append the line above it with the last field in the "batch" line.

Desired output:

user|396012_232|program|30720Mn|5108656K
|396012_232.batch|batch|30720Mn|5108656K
user|398498_2|program|102400Mn|36426336K
|398498_2.batch|batch|102400Mn|36426336K
user|391983_233|program|30720Mn|5050424K
|391983_233.batch|batch|30720Mn|5050424K

The "batch" lines would then be discarded from the output, so in those lines there is no preference if the line is cut or copied or changed in any way.

Where I got stumped, my attempts to finish the logic were embarrassingly illogical:

awk 'BEGIN{OFS="|"} {FS="|"} {if ($3=="batch") {a=$5} else {} ' file.data

Thanks!

Upvotes: 2

Views: 95

Answers (2)

user7712945
user7712945

Reputation:

if your data in 'd' file try gnu awk:

awk 'BEGIN{FS="|"} {if(getline n) {if(n~/batch/){b=split(n,a,"|");print $0 a[b]"\n"n} } }' d

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627022

If you do not need to keep the lines with batch in Field 3, you may use

awk 'BEGIN{OFS=FS="|"} NR%2==1 { prev=$0 }; $3=="batch" { print prev $5 }' file.data

or

awk 'BEGIN{OFS=FS="|"} NR%2==1 { prev=$0 }; NR%2==0 { print prev $5 }' file.data

See the online awk demo and another demo.

Details

  • BEGIN{OFS=FS="|"} - sets the field separator to pipe
  • NR%2==1 { prev=$0 }; - saves the odd lines in prev variable
  • $3=="batch" - checks if Field 3 is equal to batch (probably, with this logic you may replace it with NR%2==0 to get the even line)
  • { print prev $5 } - prints the previous line and Field 5.

You may consider also a sed option:

sed 'N;s/\x0A.*|\([^|]*\)$/\1/' file.data > newfile

See this demo

Details

  • N; - adds a newline to the pattern space, then appends the next line of input to the pattern space and if there is no more input then sed exits without processing any more commands
  • s/\x0A.*|\([^|]*\)$/\1/ - replaces with Group 1 contents a
    • \x0A - newline
    • .*| - any 0+ chars up to the last | and
    • \([^|]*\) - (Capturing group 1): any 0+ chars other than |
    • $ - end of line

Upvotes: 2

Related Questions