根据文件内容替换一行

时间:2018-10-22 22:18:25

标签: bash shell unix awk unix-timestamp

我在第二栏中有一个包含时间戳和日期的文件。如果该行包含单词之一,则需要按如下所示替换它。任何帮助表示赞赏。

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

如果我在单独的语句中添加awk则可以正常工作,但是如果我添加if语句则会出现错误。

RetryMiddleware

3 个答案:

答案 0 :(得分:1)

$ cat tst.awk
BEGIN {
    fmt["timestamp"] = "dateformat(%s,\047YYYY-MM-DD HH:NN:SS.sss\047)"
    fmt["date"]      = "dateformat(%s.\047YYYY-MM-DD\047)"
}
$2 in fmt { $0 = sprintf(fmt[$2],$1) }
{ print }

$ awk -f tst.awk file
a smallint
dateformat(b,'YYYY-MM-DD HH:NN:SS.sss')
dateformat(c.'YYYY-MM-DD')
d varchar

由于脚本位于文件中,所以我本可以使用文字',但是我使用\047,所以如果愿意,可以将其用作awk 'script' file

答案 1 :(得分:0)

当您尝试缩进代码时(在awk中可以在单引号之间使用换行符),您会看到在print之前有一个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

此代码可以“固定”为

   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

您看到您不需要else语句。 现在出现更多问题。您不应该为变量使用$3,而只需创建一个新变量。
可以在BEGIN {}部分或正常流程中将变量设置为awk参数。
我将使用带引号的变量的参数。我还介绍了startvarothervar,只是为了展示它们的工作原理。

   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

如果演示部分没有其他变量,并删除一些换行符,您将得到

   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

答案 2 :(得分:-1)

如果要在awk中使用单引号或双引号,请使用八进制表示法。 \ 047-单引号。 见下文

> cat datatype.txt
a smallint
b timestamp
c date
d varchar
> awk -F" " ' { if($2~/date/) { print "dateformat("$1".\047YYYY-MM-DD\047)" } } ' datatype.txt
dateformat(c.'YYYY-MM-DD')
> awk -F" " ' { if($2~/timestamp/) { print "dateformat("$1",\047YYYY-MM-DD HH:NN:SS.sss\047)" } } ' datatype.txt
dateformat(b,'YYYY-MM-DD HH:NN:SS.sss')
>