Skip to main content
Rollback to Revision 6
Source Link
Philippos
  • 13.7k
  • 2
  • 42
  • 82

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";").

Version by @Philippos:

With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'

Note: this version does not seem to handle the case with the newline missing between "," and "PRIMARY KEY", correctly.

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";").

Version by @Philippos:

With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'

Note: this version does not seem to handle the case with the newline missing between "," and "PRIMARY KEY", correctly.

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";").

Version by @Philippos:

With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'
added 126 characters in body
Source Link
zeppelin
  • 4k
  • 14
  • 22

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";").

Version by @Philippos:

With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'

Note: this version does not seem to handle the case with the newline missing between "," and "PRIMARY KEY", correctly.

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";").

Version by @Philippos:

With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";").

Version by @Philippos:

With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'

Note: this version does not seem to handle the case with the newline missing between "," and "PRIMARY KEY", correctly.

added 18 characters in body
Source Link
zeppelin
  • 4k
  • 14
  • 22

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";").

Version by @Philippos:

With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";"). With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'

Stream-based GNU sed solution:

#Unless on the last line, read the next line and append it to the pattern space
$!N

#If the current pair of lines in buffer, matches the "/,\nPRIMARY KEY/" pattern
/,\n\?\s*PRIMARY KEY/ { 
   #Read the following lines, until "/) ENGINE/" pattern is encountered
   :loop
   /) ENGINE/ b exit 
   N 
   b loop 
}

#Strip away everything between ", PRIMARY KEY" and ") ENGINE"
:exit
s/,\n\?\s*PRIMARY KEY.*\() ENGINE\)/\n\1/

#Print the content of the pattern space up to the first newline (i.e. the first line out of two)
P

#Delete everything up to the first newline (leaving the second line in pattern space buffer)
#and restart the cycle
D

Run as follows:

cat data.txt|sed -nf script.sed

(you can compress this to one-liner, by removing comments and replacing newlines with ";").

Version by @Philippos:

With some simplification and more portable:

sed -e '$!N;/,\n *PRIMARY KEY/!{P;D;};s/,//;:loop' -e 'N;s/ *PRIMARY KEY.*\() ENGINE\)/\1/;T loop'
\? and \s were still not portable
Source Link
Philippos
  • 13.7k
  • 2
  • 42
  • 82
Loading
exit is not neccessary and \n is undefined in the replacement string
Source Link
Philippos
  • 13.7k
  • 2
  • 42
  • 82
Loading
POSIXfied
Source Link
Philippos
  • 13.7k
  • 2
  • 42
  • 82
Loading
deleted 1 character in body
Source Link
zeppelin
  • 4k
  • 14
  • 22
Loading
Source Link
zeppelin
  • 4k
  • 14
  • 22
Loading