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?

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

3 Answers 3

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

1
  • I have modified a bit my post. The previous one was a bit ambiguous. Sorry
    – MarioRlo
    Feb 2, 2017 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

2
  • 1
    Don't cat | sed 'sedscript'; just sed 'sedscript' /path/to/file.
    – DopeGhoti
    Feb 2, 2017 at 17:04
  • I have modified a bit my post. The previous one was a bit ambiguous. Sorry
    – MarioRlo
    Feb 2, 2017 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .