Search code examples
bashshellunixawkunix-timestamp

Replace a line based upon the file content


I have a file which contains timestamp and date in the second column. If the line contains one of the word then it need to be replace like below. Any help is appreciated.

File:
a smallint
b timestamp
c date
d varchar

O/P:
a smallint
dateformat(b,'YYYY-MM-DD HH:NN:SS.sss')
dateformat(c.'YYYY-MM-DD')
d varchar

If I add awk in a seperate statement then its working but If I add if else statement then I am getting error.

awk '{if ($2=="timestamp") {$3="dataformat("; }; print $3 $1 ",'\''YYYY-MM-DD HH'\:'NN'\:'SS'\.'sss)" else ($2=="date") {$3="dataformat("; }; print $3 $1 ",'\''YYYY-MM-DD)" }' test.out 

Error:
awk: {if ($2=="timestamp") {$3="dataformat("; }; print $3 $1 ",'YYYY-MM-DD HH:NN:SS.sss)" else ($2=="date") {$3="dataformat("; }; print $3 $1 ",'YYYY-MM-DD)" }
awk: ^ syntax error
awk: {if ($2=="timestamp") {$3="dataformat("; }; print $3 $1 ",'YYYY-MM-DD HH:NN:SS.sss)" else ($2=="date") {$3="dataformat("; }; print $3 $1 ",'YYYY-MM-DD)" }
awk: ^ syntax error

Solution

  • When you try to indent your code (in awk you can use newlines between the single quotes), you will see that you have a print before the else.

       awk '{
          if ($2=="timestamp") {
             $3="dataformat(";
          };
          print $3 $1 ",'\''YYYY-MM-DD HH'\:'NN'\:'SS'\.'sss)"
          else
          ($2=="date") {
             $3="dataformat(";
          };
          print $3 $1 ",'\''YYYY-MM-DD)"
       }' test.out
    

    This code can be "fixed" with

       awk '{
          if ($2=="timestamp") {
             $3="dataformat(";
             print $3 $1 ",'\''YYYY-MM-DD HH'\:'NN'\:'SS'\.'sss)"
          }
          if ($2=="date") {
             $3="dataformat(";
             print $3 $1 ",'\''YYYY-MM-DD)"
          }
       }' test.out
    

    You see you do not need an else statement. Now more issues appear. You shouldn't use $3 for a variable, just make a new one.
    Variables can be set as an awk parameter, in a BEGIN {} section or in the normal flow.
    I would use the parameters for the variables with a single quote. I also introduced startvar and othervar, just for showing how they work.

       awk -v ymd="'YYYY-MM-DD'" \
           -v dt="'YYYY-MM-DD HH:NN:SS.sss'" \
         '
            BEGIN {
               startvar="Example variable"
            }
            $2=="timestamp" {
                printf("%s, dateformat(%s)\n", $1, ymd);
                othervar=startvar" expanded";
                print othervar;
            }
            $2=="date" {
               printf("%s, dateformat(%s)\n", $1, dt);
            }
          ' test.out
    

    Without the demo part with the additional vars, and removing some newlines, you get

       awk -v ymd="'YYYY-MM-DD'" -v dt="'YYYY-MM-DD HH:NN:SS.sss'" '
            $2=="timestamp" { printf("%s, dateformat(%s)\n", $1, ymd); }
            $2=="date" { printf("%s, dateformat(%s)\n", $1, dt); }
         ' test.out