Bash 在分析已处理数据时对数据行进行计数

Bash 在分析已处理数据时对数据行进行计数,bash,shell,parsing,awk,Bash,Shell,Parsing,Awk,我试图找到一种方法来计算在解析来自数百万个小文件的传入数据时已处理的行数 示例数据,选项卡是分隔符: CLIENT1.test.com /var DIR 21213412 user1 root default 2000-03-04 18:30:59.000000 PROC_MGMT CLIENT1.test.com /usr DIR 212112 user1 root default 2006-02-11 08:30:00.000000 PRO

我试图找到一种方法来计算在解析来自数百万个小文件的传入数据时已处理的行数

示例数据,
选项卡
是分隔符:

CLIENT1.test.com    /var    DIR 21213412    user1   root    default 2000-03-04 18:30:59.000000 PROC_MGMT
CLIENT1.test.com    /usr    DIR 212112  user1   root    default 2006-02-11 08:30:00.000000 PROC_MGMT
CLIENT2.test.com    /var/tmp/test.txt   ACTIVE  FILE    4000    sysuser sysuser NA  2001-04-11 03:00:09.000000 DEFAULT
CLIENT3.test.com    /test.out   PASSIVE FILE    4000    atuser  atgroup group   2012-05-04 02:30:59.000000 AUTOMAT
CLIENT4.test.com    /opt    DIR 542016  dbuser  dbgroup Default 2000-03-04 18:30:59.000000 SYSTEM
我的代码当前看起来像这样:

PATTERN="mssg1|mssg2|mssg3|...|mssgN"
SERVER=my_server_name

find <path> -type f -name "*.txt" -print0 | \
xargs -0 awk -v PAT="$PATTERN" '$0!~PAT' | \
awk '{gsub(/\t/",") {print}}' | \
awk -v SRV="$SERVER" 'BEGIN {FS=OFS=","} {$1=SRV OFS $1;} {if ($4 !~ /DIR/) $4=","$4;} {print}' | \
awk 'BEGIN {FS=OFS=","} {if ($9 == "") $9="01/01/1970 00:00:00 AM"; else {gsub("[:-]"," ",$9); $9=strftime("%m/%d%/Y %r", maketime($9))};} {print}' > /tmp/outputFile.log
其中xxxx可被1000整除。例如:

Processed 1000 lines out of 1000000 lines.
Processed 2000 lines out of 1000000 lines.
Processed 3000 lines out of 1000000 lines.
.........
Processed 1000000 lines out of 1000000 lines.
Done.
我可以为我正在使用的
awk
语句添加一个计数器吗

我的代码是基于运行在RHEL 6.7上的
bash
,以下程序统一了整个管道

可以对记录进行计数,但除非事先知道有多少行,否则无法打印总行数。你知道有多少文件,所以你可以用它作为计数器

PATTERN="mssg1|mssg2|mssg3|...|mssgN"
SERVER=my_server_name
find <path> -type f -name "*.txt" -print0 | \
xargs -0 awk -v PAT="$PATTERN" -v SRV="$SERVER" -v OUT=/tmp/outputFile.log '
      BEGIN {FS=OFS=","}
      (FNR==1){f++} 
      # print progress
      (NR%1000==0){ print "Processed "NR" lines and "f-1" files out of "ARGC-2 }
      # skip line matching pattern
      ($0~PAT){next}
      # substitute all tabs, prepend SRV and redefine fields
      # after this point, we inserted a new field before everything
      { gsub(/\t/,","); $0=SRV OFS $0 }
      # redefine $6 which automatically redefines fields
      # after this line, $4 will be an empty field and $5 will be the old $4
      ($4 !~ /DIR/){ $4 = OFS $4 }
      # process field 9
      { if ($9 == "") $9="01/01/1970 00:00:00 AM"
        else { gsub("[-:]"," ",$9); $9=strftime("%m/%d%/Y %r", maketime($9))} }
      # print to output file
      { print $0 > OUT }
      END{ print "Total lines processed: "NR
           print "Total files processed: "f  }'

awk
已经有一个名为
NR
的计数器,它表示记录的编号(索引)。一般情况下,记录将是一行;或者在您的情况下,是一个以null结尾的记录。只要在谷歌上搜索awk+NR,你就会找到一些例子。@Marcos,请您将示例输入和预期的示例输出发布在您的post in代码标记中,然后让我们知道。透露您的实际Awk命令可能使我们能够将整个流程重构为一个或两个Awk脚本。您所说的“我在寻找什么来计算我已经处理的行数”是什么意思输入数据?没有它,很难推断出你想做什么。例如,
{if($4!~/DIR/)$6=“,”$6;}
?您正在插入一列吗?此外,我不会帮助您创建非ISO8601的日期。如何将
结束{print”处理的总行数:“NR print”处理的总文件数:“f}”
放在另一个文件中,类似于状态文件?感谢您提供的解决方案,我将测试此代码。还有,只是一个更新。。。这个->
($4!~/DIR/){$6=OFS$6}
应该是->
($4!~/DIR/){$4=OFS$4}
。我也更新了我的代码。这需要将->
{gsub(/\t/“,”)
更新为
{gsub(/\t/,”,”)
。另外,在
(NR%1000==0){print“处理”NR行和“ARGC-2}中的“f-1”文件
,以及
print“处理的总行数:”中的NR代表什么:NR
。因为当我运行测试时,
print”处理的“NR”行
中NR的最后输出显示值17000(对于17690行),而我的样本数据中的总行数是23579,这通过
print”处理的总行数正确显示:“NR
。为什么会出现这种差距?不幸的是,我无法共享我的示例数据…**公司限制**。无论如何,我可以提供一些其他信息…首先我想,它可能是awk根据我的模式忽略的行数,但是| 1)模式匹配
忽略的行数($0~PAT){next}”
18840
| 2)如果将(1)和(2)的数量相加,则之后剩余的行数是
4739
| 3),它涉及到
23579
,这是非常有意义的。| 4)处理的行数的
17690
没有意义…只是想知道NR如何计算处理的行数。@Marcos不客气,这是我的荣幸。最后一件事,让我们清理一下现在与答案无关的评论(因为大部分是讨论和调试;-))
PATTERN="mssg1|mssg2|mssg3|...|mssgN"
SERVER=my_server_name
find <path> -type f -name "*.txt" -print0 | \
xargs -0 awk -v PAT="$PATTERN" -v SRV="$SERVER" -v OUT=/tmp/outputFile.log '
      BEGIN {FS=OFS=","}
      (FNR==1){f++} 
      # print progress
      (NR%1000==0){ print "Processed "NR" lines and "f-1" files out of "ARGC-2 }
      # skip line matching pattern
      ($0~PAT){next}
      # substitute all tabs, prepend SRV and redefine fields
      # after this point, we inserted a new field before everything
      { gsub(/\t/,","); $0=SRV OFS $0 }
      # redefine $6 which automatically redefines fields
      # after this line, $4 will be an empty field and $5 will be the old $4
      ($4 !~ /DIR/){ $4 = OFS $4 }
      # process field 9
      { if ($9 == "") $9="01/01/1970 00:00:00 AM"
        else { gsub("[-:]"," ",$9); $9=strftime("%m/%d%/Y %r", maketime($9))} }
      # print to output file
      { print $0 > OUT }
      END{ print "Total lines processed: "NR
           print "Total files processed: "f  }'
xargs ... | awk ' ... 
    END{ print "Total lines processed: "NR > "status.txt"
         print "Total files processed: "f  > "status.txt" }'