Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a SED problem beyond my knowledge. I have a solar plant that generates CSV files in the format

2012-01-08;00:00;171,297;0,000;    
2012-01-08;00:05;171,297;0,000;
2012-01-08;00:10;171,297;0,000;
2012-01-08;00:15;171,297;0,000;
2012-01-08;00:20;171,297;0,000;
2012-01-08;00:25;171,297;0,000;

I'm importing these values in a MySQL database. I would like to have a combination of the 2 first values to act as a unique primary key.

The result should look like:

2012-01-08;00:00;171,297;0,000;2012-01-08-00:00
2012-01-08;00:05;171,297;0,000;2012-01-08-00:05
2012-01-08;00:10;171,297;0,000;2012-01-08-00:10
2012-01-08;00:15;171,297;0,000;2012-01-08-00:15
2012-01-08;00:20;171,297;0,000;2012-01-08-00:20
share|improve this question
2  
Do you really need to do this in sed? –  slhck Jan 8 '12 at 20:45

3 Answers 3

I'd use awk for this, not sed:

awk -F';' ' NF {print $0 $1"-"$2}'

Where:

  • -F';': defines the input field separator
  • NF: is the number of fields, used here to filter out lines with no fields
  • $0: is the whole line
  • $1 and $2: are the first and second fields
  • The rest, I think, is self-explanatory.

Demo:

% echo '2012-01-08;00:00;171,297;0,000;

2012-01-08;00:05;171,297;0,000;

2012-01-08;00:10;171,297;0,000;

2012-01-08;00:15;171,297;0,000;

2012-01-08;00:20;171,297;0,000;

2012-01-08;00:25;171,297;0,000;' | awk -F';' ' NF {print $0 $1"-"$2}'
2012-01-08;00:00;171,297;0,000;2012-01-08-00:00
2012-01-08;00:05;171,297;0,000;2012-01-08-00:05
2012-01-08;00:10;171,297;0,000;2012-01-08-00:10
2012-01-08;00:15;171,297;0,000;2012-01-08-00:15
2012-01-08;00:20;171,297;0,000;2012-01-08-00:20
2012-01-08;00:25;171,297;0,000;2012-01-08-00:25
share|improve this answer

One way using sed:

sed 's/\(\([^;]*;\)\{2\}\)\(.*\)/\1\2\1/ ; s/;$// ; s/\(.*\);/\1-/' infile

Explanation:

s/\(\([^;]*;\)\{2\}\)\(.*\)/\1\2\1/     # Match content until second ';' and copy it at the end of the 
                                        # line.
s/;$//                                  # Delete last ';'
s/\(.*\);/\1-/                          # Substitute last ';' with '-'

Result:

2012-01-08;00:00;00:00;2012-01-08-00:00
2012-01-08;00:05;00:05;2012-01-08-00:05
2012-01-08;00:10;00:10;2012-01-08-00:10
2012-01-08;00:15;00:15;2012-01-08-00:15
2012-01-08;00:20;00:20;2012-01-08-00:20
2012-01-08;00:25;00:25;2012-01-08-00:25
share|improve this answer
    
+1: Thanks for demonstrating why I'd use awk ;) –  Johnsyweb Jan 8 '12 at 22:47

This might work for you:

 sed 'h;s/;.*//;H;g;s/\s*\n//' file
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.