1

I have a data file in the following format:

source.dat (Example for illustration purposes.)

ALBANIA Duck 1000
BELGIUM CHARLEROI Donald Duck 10234
CYPRUS J. Mickey 567

I'm looking for a Linux script (Bash, perl, whatever) to extract the info into csv format, with the given rules:

  • 1st field in csv contains only the entire words which are in uppercase
  • 3rd field in csv contains the last input field (number)
  • 2nd field in csv contains the remaining middle part

So the expected output should be:

output.csv

ALBANIA,Duck,1000
BELGIUM CHARLEROI,Donald Duck,10234
CYPRUS J.,Mickey,567
  • @Costas, can you post as an answer, with some comments? – fduff Jul 29 '16 at 20:23
  • @Costas The last part of your command should read : \1,\2/' – fduff Jul 29 '16 at 20:28
  • Sure. I misread positions of 3rd and 2nd fields from the task – Costas Jul 29 '16 at 20:34
2

Portably:

sed 's/\([^[:lower:]]*\) \(.*\) /\1,\2,/' < source.dat > output.csv
  • Fail if line have trailing spaces. Easy fixed by indicate last symbol like [^0-9] – Costas Jul 29 '16 at 21:04
  • @Costas, true, but in the dataset there's no trailing space. – fduff Jul 29 '16 at 21:05
  • @Costas, if there's a trailing space, one may argue the last field is after that trailing space and is empty. – Stéphane Chazelas Jul 29 '16 at 21:09
2

If do directly as asked

sed -r 's/([[:upper:] .]+)\s+(.*)\s+([0-9]+)\s*$/\1,\2,\3/' file

As we can see the field1 is remain on the place, so we can simplify script

sed -r 's/\s+(\w*[[:lower:]].*)\s+([0-9]+)\s*$/,\1,\2/' file

even

sed -r 's/\s+(\w*[[:lower:]].*[^0-9])\s+/,\1,/' file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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