Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在文件中搜索模式并在Unix中的命令行上删除行?_Unix_Sed_Awk_Grep - Fatal编程技术网

如何在文件中搜索模式并在Unix中的命令行上删除行?

如何在文件中搜索模式并在Unix中的命令行上删除行?,unix,sed,awk,grep,Unix,Sed,Awk,Grep,我需要在文件中搜索模式。 例如,文件内容如下: 3555005!K!00630000078!C!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078! 3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!

我需要在文件中搜索模式。 例如,文件内容如下:

3555005!K!00630000078!C!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!47001231000000!0!336344324!1!1!POST!USAGE!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
在这里我要搜索的行与!D行中的第7个字段小于系统日期,那么我想删除该行并保存文件


这有可能吗?

像这样的事情应该会奏效。。。如果字段的格式不是这样,您可能需要解析时间

perl -ne '/^([^!]+!){6}([^!]+).*/; print if $2 < time && /!D!/;'
perl-ne'/^([^!]+!){6}([^!]+)./;如果$2
如果您更喜欢AWK

awk -f logstrip.awk  in.log > out.log
logstrip.awk看起来像

# *** Simple AWK script to delete lines from log file ***
#    Rule: keep all lines except these that have their 2nd
#          field equal to "D" and their 7th field more than
#          current date time


BEGIN {
    FS = "!";   #delimiter

    stopDate = systime();
    # stopDate = 47001231000001;   for test purposes

    deletedLineCtr = 0;   #diagnostics counter, unused at this time
}

{
  if (match($2, "D") && ($7 < stopDate) ) {
    deletedLineCtr++;
  }
  else
     print $0
}
#***从日志文件中删除行的简单AWK脚本***
#规则:保留除第二行以外的所有行
#字段等于“D”,其第7个字段大于
#当前日期时间
开始{
FS=“!”;#分隔符
stopDate=systime();
#停止日期=47001231000001;用于测试目的
deletedLineCtr=0;#诊断计数器,此时未使用
}
{
如果(匹配($2,“D”)&($7<停止日期)){
deletedLineCtr++;
}
其他的
打印$0
}
我们应该做到这一点


但是,请注意,您的字段#7包含一个奇怪的日期格式。我想我知道最近的历元值(123…),但它前面有4个显然不相关的数字。根据mjv的回答,在与StopDate进行比较之前,可以很容易地删除这些字段,但是可以简化并使用(假设)日期的第五个字段(为了可读性,分为两行):


我使用文件中的样本数据进行了测试

3555005!K!00630000078!C!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!20090912000000!0!336344324!1!1!POST!vijay!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!20090912000000!0!336344324!1!1!POST!vijay!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
3555005!D!16042296!DUMMY!20090805235959!0!20090917000000!0!336344324!1!1!POST!USAGE!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!20090919000000!0!336344324!1!1!POST!USAGE!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!20090914000000!0!336344324!1!1!POST!vijay!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!20090915000000!0!336344324!1!1!POST!vijay!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!20090913000000!0!336344324!1!1!POST!vijay!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!20090912000000!0!336344324!1!1!POST!USAGE!336344324!0!
3555005!C!336344324!1!!!EUR!1!1!!I!
3555005!S!00630000078!20090805172515!LF010300!
3555005!K!204042880166840!I!20090805235959!47001231000000!16042296!336344324!A!1!ENG!0!00630000078!NO!00630000078!
3555005!D!16042296!DUMMY!20090805235959!0!20090912000000!0!336344324!1!1!POST!USAGE!336344324!0!
但是它正在删除所有包含的行!D 我使用了以下awk脚本

# *** Simple AWK script to delete lines from log file ***
#    Rule: keep all lines except these that have their 2nd
#    field equal to "D" and their 7th field more than
#          current date time
BEGIN {
       FS = "!";
         #delimiter
         stopDate = "date +%Y%m%d%H%M%S";
         # stopDate = 47001231000001;  for test purposes
         deletedLineCtr = 0;   #diagnostics counter, unused at this time
      }
      {
      if ( match($2, "D") && ($7 < stopDate) )
          {
           deletedLineCtr++;
          }
      else
           print $0
      }
#***从日志文件中删除行的简单AWK脚本***
#规则:保留除第二行以外的所有行
#字段等于“D”,其第7个字段大于
#当前日期时间
开始{
FS=“!”;
#分隔符
stopDate=“日期+%Y%m%d%H%m%S”;
#停止日期=47001231000001;用于测试目的
deletedLineCtr=0;#诊断计数器,此时未使用
}
{
如果(匹配($2,“D”)&($7<停止日期))
{
deletedLineCtr++;
}
其他的
打印$0
}

我做错了什么吗?

请将示例数据格式化为代码块,您可以通过编辑问题、选择文本并按CTRLKIt键来实现这一点。这可能是第五个字段。顺便说一下,不要打印“zz”和$0,只需颠倒测试逻辑,只打印(不)匹配的行。Thks,Dennis W,这个“zz”东西是一些测试时间代码,我在发布之前忘记清理。。。我清理了这个,没有逆转测试(但这是一个好主意,因为我们不做任何有用的w/deletedLineCtr)!“print$0”是冗余的——只需“print”即可。事实上,如果这是awk程序中的最后一个操作,您可以完全忽略该操作,因为它是默认操作:awk-F-v日期=$(日期'+%Y%m%d%H%m%S')”$2!=“D”| |$5>=日期“你说得对。但是,我将保留
打印
,以避免太多混淆。请使用代码和blockquote功能格式化您的帖子,使其可读。Awk没有这样的“date”命令。此外,我不认为“47001231000001”是一个日期(除非你去掉“4700”,那么它看起来像是从纪元算起的秒数)。在您的第一篇文章中,该值位于字段7中,但字段5看起来像一个日期。在本文中,该值位于某些记录的字段6中,但字段7看起来像一个日期。看看我的答案或mjv的。如果选择了正确的字段,则这两种方法都应该有效。继续努力。你快到了。
# *** Simple AWK script to delete lines from log file ***
#    Rule: keep all lines except these that have their 2nd
#    field equal to "D" and their 7th field more than
#          current date time
BEGIN {
       FS = "!";
         #delimiter
         stopDate = "date +%Y%m%d%H%M%S";
         # stopDate = 47001231000001;  for test purposes
         deletedLineCtr = 0;   #diagnostics counter, unused at this time
      }
      {
      if ( match($2, "D") && ($7 < stopDate) )
          {
           deletedLineCtr++;
          }
      else
           print $0
      }