0

I have lines like this in a file

x;x;x;x;x;x;cmd="lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x

x;x;x;x;x;x;cmd="lbk_dropcolumn TABLE_NAME_2 COLUMN_Y";x;x;x;x

I wish to replace the field with "cmd" in the file to something like this :

x;x;x;x;x;x;cmd="ColumnAdded TABLE_NAME_1 COLUMN_X || lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x

x;x;x;x;x;x;cmd="ColumnDropped TABLE_NAME_2 COLUMN_Y || lbk_dropcolumn TABLE_NAME_2 COLUMN_Y ";x;x;x;x

How can I do this?

  • 2
    Shouldn't the last line contain "lbk_dropcolumn" instead of "lbk_addcolumn" ? – ka3ak Feb 2 '17 at 16:45
0

You can try this Bash script:

while read ln; do
    out=`sed 's/\([^"]*\)"\([^"]*\)\(.*\)/\1"\2 || \2\3/' <<< "$ln"`
    out=`sed -e 's/lbk_addcolumn/ColumnAdded/' -e 's/lbk_dropcolumn/ColumnDropped/' <<< "$out"`
    echo "$out"
done < input.txt

where input.txt contains your lines

  • I have modified a bit my post. The previous one was a bit ambiguous. Sorry – MarioRlo Feb 2 '17 at 17:45
0
sed -r -e "s/(lbk_addcolumn.*)(\[.*\])\s*(\[.*\])/ColumnAdded \2 \3 || \1 \2 \3/g" \ 
-e "s/(lbk_dropcolumn.*)(\[.*\])\s*(\[.*\])/ColumnDropped \2 \3 || \1 \2 \3/g" input.txt

where input.txt is your content

  • 1
    Don't cat | sed 'sedscript'; just sed 'sedscript' /path/to/file. – DopeGhoti Feb 2 '17 at 17:04
  • I have modified a bit my post. The previous one was a bit ambiguous. Sorry – MarioRlo Feb 2 '17 at 17:45
0

Instead of ugly sed regex patterns, If all the lines have the same fixed format like your two lines (6*x;cmd="...";4*x), bellow alternative commands does the job in the file, without requiring a file read loop.

Key point (if format is steady across all lines) is the use of the " as delimiter, cutting the lines in 3 separate fields.

$ sed 's/lbk_addcolumn/ColumnAdd/;s/lbk_dropcolumn/ColumnDrop/' <(awk -F'"' '{if (($0=="")) print $0;else print $1"\""$2" || "$2"\""$3}' file.txt)

Or :

$ a=$(awk -F'"' '{if (($0=="")) print $0;else print $1"\""$2" || "$2"\""$3}' file.txt)
$ sed 's/lbk_addcolumn/ColumnAdd/;s/lbk_dropcolumn/ColumnDrop/' <<<"$a"

awk splits each line of file with " as delimiter.
if $0="" then it is a blank line, print the blank line and go on else print all line fields in required order.

Finally sed replaces the first found text lbk_addcolumn with ColumnAdd.

Test:

$ cat e.txt
x;x;x;x;x;x;cmd="lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x

x;x;x;x;x;x;cmd="lbk_dropcolumn TABLE_NAME_2 COLUMN_Y";x;x;x;x

# sed 's/lbk_addcolumn/ColumnAdd/;s/lbk_dropcolumn/ColumnDrop/' <(awk -F'"' '{if (($0=="")) print $0;else print $1"\""$2" || "$2"\""$3}' e.txt)
x;x;x;x;x;x;cmd="ColumnAdd TABLE_NAME_1 COLUMN_X || lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x

x;x;x;x;x;x;cmd="ColumnDrop TABLE_NAME_2 COLUMN_Y || lbk_dropcolumn TABLE_NAME_2 COLUMN_Y";x;x;x;x

Same result can be achieved even only with awk and the use of the gsub awk function:

$ awk -F'"' '{if ($0=="") print $0;else {a=$2;gsub("lbk_addcolumn","ColumnAdd",$2);gsub("lbk_dropcolumn","ColumnDrop",$2);print $1"\""$2" || "a"\""$3;}}' e.txt
x;x;x;x;x;x;cmd="ColumnAdd TABLE_NAME_1 COLUMN_X || lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x

x;x;x;x;x;x;cmd="ColumnDrop TABLE_NAME_2 COLUMN_Y || lbk_dropcolumn TABLE_NAME_2 COLUMN_Y";x;x;x;x

awk better presentation:

    $ awk -F'"' '{
      if ($0=="") print $0;
      else {
        a=$2;
        gsub("lbk_addcolumn","ColumnAdd",$2);
        gsub("lbk_dropcolumn","ColumnDrop",$2);
        print $1"\""$2" || "a"\""$3;
           }
                 }' e.txt

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.