使用awk或sed查找字符串的第一个和最后一个匹配项

时间:2015-04-02 22:36:53

标签: unix awk sed

我无法找到我在网上寻找的内容,所以我希望有人可以帮助我。我有一个包含以下行的文件:

  

CON /类型/ abc.sql
  CON /类型/ bcd.sql
  CON /表/ last.sql
  CON /表/ first.sql
  CON /功能/ abc.sql
  CON /包装/ foo.sql

我想要做的是找到第一次出现的Table,打印一个新字符串,然后查找最后一次出现并打印另一个字符串。例如,输出应如下所示:

  

CON /类型/ abc.sql
  CON /类型/ bcd.sql
  set define on   CON /表/ last.sql
  CON /表/ first.sql
  set define off   CON /功能/ abc.sql
  CON /包装/ foo.sql

如您所见,在第一次出现表I之后,在第一次出现之前打印了“set define on”。对于最后一次出现,我在表的最后一次匹配后打印了“set define off”。有人可以帮我写一个awk脚本吗?使用sed也没关系。

注意:带有表格的行可以显示在文件的第一行或中间或最后一行。在这种情况下,它们出现在其余行的中间。

1 个答案:

答案 0 :(得分:2)

$ awk -F/ '$2=="Table"{if (!f)print "set define on";f=1} f && $2!="Table"{print "set define off";f=0} 1' file
CON/Type/abc.sql
CON/Type/bcd.sql
set define on
CON/Table/last.sql
CON/Table/first.sql
set define off
CON/Function/abc.sql
CON/Package/foo.sql

如何运作

  • -F/

    将字段分隔符设置为/

  • $2=="Table"{if (!f)print "set define on";f=1}

    如果第二个字段为Table,请执行以下操作:(a)如果标记f为零,则打印set define on; (b)将标志f设为一(真)。

  • f && $2!="Table"{print "set define off";f=0}

    如果标记f为真且第二个字段不是Table,请执行以下操作:(a)打印set define off; (b)将标志f设为零(假)。

  • 1

    打印当前行。

替代版本

正如Etan Reisner所建议的那样,以下内容对逻辑进行了轻微的重组,无需使用if语句:

awk -F/ '$2=="Table" && !f {print "set define on";f=1} $2!="Table" && f {print "set define off";f=0} 1' file