-1

I am trying to format a database script and I need to remove the last " , " from the lines that are before ")," but I have not been successful ...

This is the input file

DROP TABLE IF EXISTS attribute_type;
CREATE TABLE attribute_type (
  attribute_type_id int(11) NOT NULL,
  name varchar(30) COLLATE es_CO.UTF-8 NOT NULL,
  description text COLLATE es_CO.UTF-8,
  is_set smallint(6) DEFAULT NULL,    <-- Here is the last character I want to remove
),


DROP TABLE IF EXISTS attribute_type_options;
CREATE TABLE attribute_type_options (
  attribute_type_options_id int(11) NOT NULL,
  person_attribute_type_id int(11) DEFAULT NULL,
  name varchar(60) COLLATE es_CO.UTF-8 NOT NULL,
  default_value bit(1) DEFAULT NULL,    <-- Here is the last character I want to remove
),

This should be the output

DROP TABLE IF EXISTS attribute_type;
CREATE TABLE attribute_type (
  attribute_type_id int(11) NOT NULL,
  name varchar(30) COLLATE es_CO.UTF-8 NOT NULL,
  description text COLLATE es_CO.UTF-8,
  is_set smallint(6) DEFAULT NULL
),


DROP TABLE IF EXISTS attribute_type_options;
CREATE TABLE attribute_type_options (
  attribute_type_options_id int(11) NOT NULL,
  person_attribute_type_id int(11) DEFAULT NULL,
  name varchar(60) COLLATE es_CO.UTF-8 NOT NULL,
  default_value bit(1) DEFAULT NULL
),

I tried this solution but it does the change in all lines , not just where I need Thank you for your help !!!

Community
  • 1
  • 1

5 Answers5

0

This perl command line can handle this:

perl -0pe 's/,(?=\n\),\n)//g' file
DROP TABLE IF EXISTS attribute_type;
CREATE TABLE attribute_type (
  attribute_type_id int(11) NOT NULL,
  name varchar(30) COLLATE es_CO.UTF-8 NOT NULL,
  description text COLLATE es_CO.UTF-8,
  is_set smallint(6) DEFAULT NULL
),


DROP TABLE IF EXISTS attribute_type_options;
CREATE TABLE attribute_type_options (
  attribute_type_options_id int(11) NOT NULL,
  person_attribute_type_id int(11) DEFAULT NULL,
  name varchar(60) COLLATE es_CO.UTF-8 NOT NULL,
  default_value bit(1) DEFAULT NULL
),
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

Try doing this :

perl -0pe 's/,\s*\n\)/\n)/g' file

NOTE

  • -0 permit perl to read the whole file instead of line by lines
  • -p is like using while (<>) {} construct and print each lines like sed
  • s/,\n\)/\n)/g is a regex substitution

Another solution

using pure :

while read line; do
    if [[ $line =~ ^\),\s* ]]; then
        echo "${lastline%,}"
    else
        echo "$lastline"
    fi

    lastline="$line"
done < file
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
0

I don't have enough reputation to comment, but just want to add to @anubhava's answer:

He suggested: perl -0pe 's/,(?=\n\),\n)//g' file.

I think this should be changed to perl -0pe 's/,(?=\s*\n\),\n)//g' file in case there is trailing whitespace.

  • Excellent, so just for adding an optional `\s*` in lookahead it became a correct answer where as all the 99.99% effort was mine. Do you even realize that `\s` also matches `\n`? – anubhava Nov 18 '14 at 15:29
  • Hey man, I explicitly stated it was just an addition to your comment. And yes, it also matches a new line, which is completely okay. – rottweilers_anonymous Nov 18 '14 at 15:31
  • 1
    You need 50 rep to comment on answers! I was at 49. And now he has changed the accepted answer... so there you go. – rottweilers_anonymous Nov 18 '14 at 15:38
0

Try this:

sed -n 'H;${;g; s/\([^,]\),\n)/\1\n)/g;p}' file.sql
rook
  • 5,880
  • 4
  • 39
  • 51
0

An awk version:

 awk '/^\),$/{a=substr(a, 0, length(a))} {print a;a=$0}END{print a}' f

a "stores" the previous line. For each line, you print the previous (print a;), and assign the line in a (a=$0)

But if the line consists of only ), (/^\),$/) then delete the last char before doing the printing/storing (a=substr(a, 0, length(a))).

At the end (END{...) print the last line.

fredtantini
  • 15,966
  • 8
  • 49
  • 55