多线图案/数据提取

多线图案/数据提取

我在大约100,000个文件中有以下标题,我已经分别提取了每一行并将每条记录合并到Excel中,所以我的时间紧迫已经结束,我现在正在寻找一种便捷的数据提取方法。

X-RSMF-Generator:RSMF 生成器示例库

X-RSMF 版本:1.0.0

X-RSMF-事件计数:53

X-RSMF-开始日期:2022-09-20T04:33:11-04:00

X-RSMF-结束日期:2022-09-20T16:47:56-04:00

X-RSMF-组ID:GRP000000118

X-RSMF-辅助组ID:GRP000000118_D_20220920

X-RSMF-包含已删除:错误的

X-RSMF-应用:原生消息

X-RSMF 参与者:第一人<5156242756>第二人、第二人

[电子邮件受保护]<21243210277> 四人 *** <345278652345>

MIME 版本:1.0

并非所有文件中都存在所有行,并且最后一个字段可以包含多行。 MIME 版本:1.0 - 我认为我们可以使用MIME 版本:1.0作为停靠站。我也只需要每行条目的数据。 “:”(冒号空格)之前的所有内容都可以忽略,因为它们是字段标题。

我开始使用 sed,认为我可以将每行和管道连接到 AWK。制作每一列。

#!/bin/sh

shopt -s nullglob
FILES=/mnt/c/Temp/rsmf/*.rsmf

for f in $FILES

do
    #echo "Processing $f"
    sed -rn \
    -e '/^X-RSMF-BeginDate:/{
        s/X-RSMF-BeginDate: //
        s/T/ /
        s/-0[45]:00/ /
        s/X-RSMF-Application://
        h
        #p
        }' \
    -e '/^X-RSMF-EndDate:/{
        s/X-RSMF-EndDate: //
        s/T/ /
        s/-0[45]:00/ /
        H
        #p
        }' \
     -e '/^X-RSMF-GroupID:/{
        s/X-RSMF-GroupID: //
        H
        x
        s/\r\n//gp
        }' \
         $f
done

结果 -

2022-10-05 12:54:27 2022-10-05 12:54:27 GRP000000001
2022-10-05 11:48:18 2022-10-05 11:48:18 GRP000000002

在花时间讨论这个问题之前,我想寻求有关该特定项目的最佳方法和实践的建议。

想法??

答案1

awk -F': ' 'BEGIN{ORS=" "}$1=="MIME-Version"{exit}{print $2}END{print "\n"}' file    

答案2

以下是相当老套和暴力的方法,可能有更好的方法(但我需要更多地了解您的数据以及为什么您甚至提到 Excel - 如果数据最初位于电子表格中,那么是用于直接从 Excel 或 Open/Libre Office 等提取数据的 Perl 模块,但它确实可以使用您提供的示例数据。

它可以处理任意数量的输入文件。

它已被编写为使用 TAB (\t或 Ctrl-I 或^I)作为输出字段分隔符,而不是空格因为您的字段数据可以包含空格

#!/usr/bin/perl

while (<>) {
  chomp;
  s/^\s*|\s*$//g;  # strip any leading and trailing whitespace
  next if /^$/;    # ignore all blank lines

  # split input line into @F array
  # $F[0] will contain the field name and
  # $F[1] will contain the field data
  # The field separator is a quite-forgiving zero-or-more spaces followed by
  # a colon followed by one-or-more spaces. This should cope with most minor
  # variants caused by manual extraction from Excel. 
  my @F = split /\s*:\s+/;

  # print the data at end of each input record (file)
  if (/^MIME-Version/) {
    # add space-separated @participants array to end of @record array
    push @record, join(" ", @participants);

    # print @record array, tab-separated
    print join("\t", @record), "\n";

    # clear both arrays, ready for next input file
    @record=();
    @participants=();
    next;
  };

  # fix up the date format
  if (/^X-RSMF-(Begin|End)Date/) {
    $F[1] =~ s/T/ /;
    $F[1] =~ s/-0[45]:00$//;
  };

  if (/^X-RSMF-Participants/) {
    # participants need to be handled differently because this field can
    # be multi-line.  Store in a separate @participants array
    push @participants, $F[1];

  } elsif ($#F == 0) {
    # lines without a field name get added to @participants array
    push @participants, $_;

  } else {
    # all other fields get added to @record array
    push @record, $F[1];
  }
}

将其保存到文件中,例如rsmf2tab.pl,使其可执行chmod +x rsmf2tab.pl,然后运行它,例如

./rsmf2tab.pl /mnt/c/Temp/rsmf/*.rsmf

或者如果您的 .rsmf 文件位于多个子目录中:

find /mnt/c/Temp/rsmf/ -name '*.rsmf' -exec /path/to/rsmf2tab.pl {} +

示例输出以两个示例数据副本(如 file1.rsmf 和 file2.rsmf)作为输入,通过管道传输cat -A以将选项卡显示为^I

$ ./rsmf2tab.pl *.rsmf | cat -A
RSMF Generator Sample Library^I1.0.0^I53^I2022-09-20 04:33:11^I2022-09-20 16:47:56^IGRP000000118^IGRP000000118_D_20220920^IFalse^INative Messages^IPerson One <5156242756> Person two, Person three [email protected] <21243210277> Person four <345278652345>$
RSMF Generator Sample Library^I1.0.0^I53^I2022-09-20 04:33:11^I2022-09-20 16:47:56^IGRP000000118^IGRP000000118_D_20220920^IFalse^INative Messages^IPerson One <5156242756> Person two, Person three [email protected] <21243210277> Person four <345278652345>$

顺便说一句,你真的不想再做你的FILE=/mnt/c/Temp/rsmf/*.rsmf后继者for f in $FILES。如果任何文件包含任何空白字符,这将会中断。无论如何,这不是必需的 - 只需运行for f in /mnt/c/Temp/rsmf/*.rsmf或(取决于您正在运行的内容),只需将所有文件名参数传递给您正在运行的命令而不使用循环。

相关内容