Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.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
bashshell脚本:根据字段分隔符计算文件中每个段落的行数?_Bash_Shell_Awk - Fatal编程技术网

bashshell脚本:根据字段分隔符计算文件中每个段落的行数?

bashshell脚本:根据字段分隔符计算文件中每个段落的行数?,bash,shell,awk,Bash,Shell,Awk,我想分析日志文件,但在这种情况下卡住了: 例如: 我有一个格式如下的文件: 140508 0:00:19 10 abc def 9 djdj djdjd 12 fjfj fjfjj 140508 0:00:24 10 dhdh dhdh 19 dddh hdhdhd 1838 jcjj ddhfhfh 17

我想分析日志文件,但在这种情况下卡住了:

例如: 我有一个格式如下的文件:

140508  0:00:19 10 abc  def
            9  djdj djdjd
            12 fjfj fjfjj                       
140508  0:00:24         10 dhdh dhdh
            19 dddh  hdhdhd
            1838 jcjj ddhfhfh
            17 fhfhh fhfhfh
140508  0:00:29         10 ababa cbcbc
字段分隔符为140508(年月日)

我想根据字段分隔符输出每个段落中的行数:

140508  0:00:19 3
140508  0:00:24 4
140508  0:00:29 1
谢谢。

使用awk:

awk '/^[0-9]{6} /{if (c) print a, b, c; a=$1; b=$2; c=1; next} {c++} END{print a, b, c}' file
140508 0:00:19 3
140508 0:00:24 4
140508 0:00:29 1
使用awk:

awk '/^[0-9]{6} /{if (c) print a, b, c; a=$1; b=$2; c=1; next} {c++} END{print a, b, c}' file
140508 0:00:19 3
140508 0:00:24 4
140508 0:00:29 1
使用awk

awk '/:/{h=$1 FS $2}{a[h]++}END{for (i in a) print i,a[i]}' file
解释
  • /:/{h=$1fs$2}
    ,仅在
    行上工作,并生成数组a的索引
  • {a[h]+}
    对该索引上的时间求和
  • {对于(a中的i)print i,a[i]}
    遍历数组a并执行打印作业
使用awk

awk '/:/{h=$1 FS $2}{a[h]++}END{for (i in a) print i,a[i]}' file
解释
  • /:/{h=$1fs$2}
    ,仅在
    行上工作,并生成数组a的索引
  • {a[h]+}
    对该索引上的时间求和
  • {对于(a中的i)print i,a[i]}
    遍历数组a并执行打印作业

    • 使用GNU
      awk

      awk --re-interval -v RS='(^|\n)[0-9]{6} ' \
       '$0=="" {sep=RT; next}  {print sep $1, 1+gsub("\n.",""); sep=substr(RT,2)}'  file
      
      注意:如果您的
      gawk
      版本为>=
      4.0
      ,则不需要
      --re interval
      选项

      说明:

      • 日期表达式
        [0-9]{6}
        用作记录分隔符(
        RS
        ),它自动将输入拆分为所需的段落;在前面加上
        (^ |\n)
        可确保仅在行的开头执行匹配
      • RT
        包含与手头记录的
        RS
        regex匹配的文字记录终止符;它保存在
        sep
        变量中,用于处理下一条记录。
        • 请注意,由于输入以记录分隔符开头,因此报告的第一条记录为空-因此出现了
          $0==“”
          模式和相关操作
        • 对于所有后续记录,必须将inital
          \n
          切掉分隔符,这是
          substr()
          调用所做的
      • 1+gsub(“\n.,”)
        是一个小技巧,它可以有效地简单地计算记录中非空行的数量(
        gsub()
        返回替换的数量)

        • 使用GNU
          awk

          awk --re-interval -v RS='(^|\n)[0-9]{6} ' \
           '$0=="" {sep=RT; next}  {print sep $1, 1+gsub("\n.",""); sep=substr(RT,2)}'  file
          
          注意:如果您的
          gawk
          版本为>=
          4.0
          ,则不需要
          --re interval
          选项

          说明:

          • 日期表达式
            [0-9]{6}
            用作记录分隔符(
            RS
            ),它自动将输入拆分为所需的段落;在前面加上
            (^ |\n)
            可确保仅在行的开头执行匹配
          • RT
            包含与手头记录的
            RS
            regex匹配的文字记录终止符;它保存在
            sep
            变量中,用于处理下一条记录。
            • 请注意,由于输入以记录分隔符开头,因此报告的第一条记录为空-因此出现了
              $0==“”
              模式和相关操作
            • 对于所有后续记录,必须将inital
              \n
              切掉分隔符,这是
              substr()
              调用所做的
          • 1+gsub(“\n.,”)
            是一个小技巧,它可以有效地简单地计算记录中非空行的数量(
            gsub()
            返回替换的数量)

          • 这似乎是错的。我使用上面的示例运行您的脚本,结果显示:“140508 0:00:29 8”我还提供了awk命令的输出。这和你预期的输出不一样吗?你能在脚本中解释一下(c)吗。是的,你的结果是正确的,但当我运行它时,会给我另一个结果。[root@TESTSRV用户]#cat测试140508 0:00:19 10 abc def 9 djdj DJD 12 fjfj FJFJJ140508 0:00:24 10 DHDHDH 19 DDDHHDHD 1838 jcjj DDHFH 17 FHFHFHFHFH140508 0:00:29 10 ababa CBC[root@TESTSRV用户]#awk'/[0-9]{6}/{如果(c)打印$1,$2,c;c=1;下一个}{c++}END{print$1,$2,c}test 140508 0:00:29 8
            c
            只是一个计数器,每次匹配模式时,它都以
            1
            开头。如果您遇到问题,请在您的问题中提供一个可以重现问题的示例输入,我将相应地调整我的命令+1.您的解决方案甚至与POSIX兼容。(在GNU
            awk
            <4上,您必须添加
            --posix
            --re interval
            使其工作。)锚定正则表达式并添加空格将有助于健壮性-
            /^[0-9]{6}/
            。这似乎是错误的。我使用上面的示例运行您的脚本,结果显示:“140508 0:00:29 8”我还提供了awk命令的输出。这和你预期的输出不一样吗?你能在脚本中解释一下(c)吗。是的,你的结果是正确的,但当我运行它时,会给我另一个结果。[root@TESTSRV用户]#cat测试140508 0:00:19 10 abc def 9 djdj DJD 12 fjfj FJFJJ140508 0:00:24 10 DHDHDH 19 DDDHHDHD 1838 jcjj DDHFH 17 FHFHFHFHFH140508 0:00:29 10 ababa CBC[root@TESTSRV用户]#awk'/[0-9]{6}/{如果(c)打印$1,$2,c;c=1;下一个}{c++}END{print$1,$2,c}test 140508 0:00:29 8
            c
            只是一个计数器,每次匹配模式时,它都以
            1
            开头。如果您遇到问题,请在您的问题中提供一个可以重现问题的示例输入,我将相应地调整我的命令+1.您的解决方案甚至与POSIX兼容。(在GNU
            awk
            <4上,您必须添加
            --posix
            --re interval
            以使其工作。)锚定正则表达式并附加空格将有助于健壮性-
            /^[0-9]{6}/
            。这对我来说很有用。你能解释一下你的剧本吗??谢谢。它很简洁,但请注意,由于在中使用了
            i,因此输出行的顺序与输入顺序不匹配。此外,与
            /^[0-9]匹配