从大型固定宽度文本中解析未排序的数据

2023-12-05

我主要是一个 Matlab 用户和 Perl n00b。这是我的第一个 Perl 脚本。

我有一个大型固定宽度数据文件,我想将其处理成带有目录的二进制文件。我的问题是数据文件非常大,并且数据参数按时间排序。这使得解析到 Matlab 变得困难(至少对我来说)。因此,看到 Matlab 不太擅长解析文本,我想我应该尝试 Perl。我编写了以下代码,该代码可以工作......至少在我的小测试文件上。然而,当我在实际的大数据文件上尝试时,速度非常慢。它是从 Web/Perl 文档中拼凑而成的各种任务的大量示例。

这是数据文件的一个小样本。注:真实文件大约有2000个参数,大小为1-2GB。参数可以是文本、双精度数或无符号整数。

Param 1   filter = ALL_VALUES
Param 2   filter = ALL_VALUES
Param 3   filter = ALL_VALUES

Time                     Name     Ty  Value                   
---------- ---------------------- --- ------------
1.1        Param 1                UI  5           
2.23       Param 3                TXT Some Text 1 
3.2        Param 1                UI  10          
4.5        Param 2                D   2.1234     
5.3        Param 1                UI  15         
6.121      Param 2                D   3.1234     
7.56       Param 3                TXT Some Text 2 

我的脚本的基本逻辑是:

  1. 阅读直到 ---- 行来构建要提取的参数列表(始终具有“filter =”)。
  2. 使用 --- 行确定字段宽度。它被空格打破了。
  3. 对于每个参数构建时间和数据数组(嵌套在 foreach 参数内)
  4. In continue块将时间和数据写入二进制文件。然后在文本目录文件中记录名称、类型和偏移量(用于稍后将文件读入 Matlab)。

这是我的脚本:

#!/usr/bin/perl

$lineArg1 = @ARGV[0];
open(INFILE, $lineArg1);
open BINOUT, '>:raw', $lineArg1.".bin";
open TOCOUT, '>', $lineArg1.".toc";

my $line;
my $data_start_pos;
my @param_name;
my @template;
while ($line = <INFILE>) {
    chomp $line;
    if ($line =~ s/\s+filter = ALL_VALUES//) {
       $line = =~ s/^\s+//;
       $line =~ s/\s+$//;
       push @param_name, $line;
    }
    elsif ($line =~ /^------/) {
        @template = map {'A'.length} $line =~ /(\S+\s*)/g;
        $template[-1] = 'A*';        
        $data_start_pos = tell INFILE;
        last; #Reached start of data exit loop
    }
}
my $template = "@template";
my @lineData;
my @param_data;
my @param_time;
my $data_type;
foreach $current_param (@param_name) {
    @param_time = ();
    @param_data = ();    
    seek(INFILE,$data_start_pos,0); #Jump to data start
    while ($line = <INFILE>) {
        if($line =~ /$current_param/) {      
           chomp($line);
           @lineData = unpack $template, $line;
           push @param_time, @lineData[0];   
           push @param_data, @lineData[3];
        }       
    } # END WHILE <INFILE>
} #END FOR EACH NAME
continue {
        $data_type = @lineData[2];
        print TOCOUT $current_param.",".$data_type.",".tell(BINOUT).","; #Write name,type,offset to start time        
        print BINOUT pack('d*', @param_time);  #Write TimeStamps
        print TOCOUT tell(BINOUT).","; #offset to end of time/data start
        if ($data_type eq "TXT") {
            print BINOUT pack 'A*', join("\n",@param_data);
        }
        elsif ($data_type eq "D") {
            print BINOUT pack('d*', @param_data);
        }
        elsif ($data_type eq "UI") {
            print BINOUT pack('L*', @param_data);
        }        
        print TOCOUT tell(BINOUT).","."\n"; #Write memory loc to end data
}
close(INFILE);
close(BINOUT);
close(TOCOUT);

所以我向各位网络上的好心人提出以下问题:

  1. 我明显搞砸了什么?语法、不需要时声明变量等。
  2. 由于嵌套循环和一遍又一遍地逐行搜索,这可能很慢(猜测)。有没有更好的方法来重构循环以一次提取多行?
  3. 您还可以提供其他任何提高速度的技巧吗?

编辑:我修改了示例文本文件以说明非整数时间戳和参数名称可能包含空格。


首先,你应该始终拥有'使用严格;'和“使用警告”;脚本中的编译指示.

看来你需要一个简单的数组(@param_name)作为参考,因此加载这些值将非常简单。 (同样,添加上述编译指示将开始向您显示错误,包括$line = =~ s/^\s+//; line!)

我建议您阅读本文,了解如何将数据文件加载到哈希值的哈希值。一旦设计了哈希值,您只需读取并加载文件数据内容,然后迭代哈希值的内容即可。

例如,使用时间作为哈希的键

%HoH = (
    1 => {
        name   => "Param1",
        ty       => "UI",
        value       => "5",
    },
    2 => {
        name   => "Param3",
        ty       => "TXT",
        value       => "Some Text 1",
    },
    3 => {
        name   => "Param1",
        ty       => "UI",
        value       => "10",
    },
);

确保在读入内容后、开始处理之前关闭 INFILE。

所以最后,您迭代哈希,并引用数组(而不是文件内容)来进行输出写入 - 我想它会是much更快地做到这一点。

如果您需要更多信息,请告诉我。

注意:如果您走这条路线,请包括数据:自卸车- 对打印和理解散列中的数据有很大帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从大型固定宽度文本中解析未排序的数据 的相关文章

  • 在 FOR 循环中打印唯一值

    我有两个文件 myresult 和 annotation 两个文件中的数据似乎是范围 但事实并非如此 这就是为什么我无法将其存储在数组中 我需要使用拆分运算符 以便我可以在 for 循环中使用它并进行比较 现在我需要打印 i myresul
  • 如何使用 Perl 正则表达式匹配字符串末尾/开头处的空格或单词?

    我想找到与我的正则表达式匹配的序列 它们应该位于由空格包围的字符串中间 末尾或开头或者是字符串中唯一的东西 Example 我们假设序列 qwe45rty 就是我们正在寻找的 我希望能够对所有这些因素都抱有积极的态度 qwe45rty qw
  • 如何编写 Perl 脚本来使用 curl 处理 URL?

    我有一个非常简单的任务 我有一个 crontab 每小时运行一个脚本 该脚本旨在简单地处理 URL 这就是我所拥有的 这不起作用 我收到语法错误 usr bin perl curl http domain com page html 我已经
  • 正则表达式从字符串中提取 IP 和端口

    我正在使用 Perl 尝试从字符串中提取 IP 地址和端口 我尝试使用的正则表达式是 s sip 字符串是 sip 255 255 255 255 8080 transport TCP sip 255 255 255 255 8080 显然
  • Perl 是否有相当于 Python 的 `if __name__ == '__main__'` 的功能?

    有没有一种方法可以确定当前文件是否是 Perl 源中正在执行的文件 在 Python 中 我们使用以下结构来做到这一点 if name main This file is being executed raise NotImplemente
  • 如何将 Perl 转换为 C?

    有没有可用的工具可以将 Perl 源代码转换为 C 源代码 什么平台都可以 对此的规范答案是MJD 的 为什么不将 Perl 翻译成 C http www perl com pub a 2001 06 27 ctoperl html
  • 如何使用 Perl CGI 脚本提供图像?

    我的 Google fu 让我失望了 如何使用 Perl 提供已生成的图像 Example img src getimage pl getimage pl 里有什么 干得好 usr bin perl w my file inner nav
  • Perl Parallel::Forkmanager 不允许收集变量值

    也许因为子进程不知道我的散列 请参阅下面的代码 散列 输出没有收集任何内容 除了写入 tmp 文件之外 还有其他方法来收集该值吗 foreach Item AllItems pid pm gt start Item and next Tem
  • Perl 语言的目标是在运行时生成快速的程序吗?

    最近有朋友告诉我 看 Perl 从来就不是为了快而设计的 真的吗 我能找到的相关信息是来自维基百科 http en wikipedia org wiki Perl Overview 该语言旨在实用 易于使用 高效 完整 而不是美观 微小 优
  • 使用 Cygwin 安装 CPAN GD 模块失败

    我已经尝试解决为什么 CPAN GD 模块无法使用 Cygwin 安装 2 天了 任何帮助深表感谢 谢谢 cpan install GD Going to read home xxxxxxxxxx cpan Metadata Databas
  • 折叠具有多个字段的行

    我有这个代码 awk seen 1 2 a 1 a 1 a 1 t 2 END for i in a print i a i inputfile 我想折叠具有两个以上字段的行 但始终基于第一个字段作为索引 输入文件 三列制表符分隔 prot
  • 如何在 Perl 中获取本周的日期?

    我有以下循环来计算本周的日期并将其打印出来 它有效 但我正在考虑 Perl 中日期 时间可能性的数量 并且想听听您对是否有更好的方法的意见 这是我写的代码 usr bin env perl use warnings use strict u
  • 如何在 Perl 脚本中加密或隐藏密码?

    我正在研究 Perl 脚本 它使用Expect http search cpan org dist Expect通过 telnet 登录到远程计算机 不要问 必须使用 telnet 我还根据需要执行 perforce p4 登录操作 并使用
  • 如何忽略 perl 中的“证书验证失败”错误?

    我想访问一个无法验证证书的网站 我正在使用 WWW Mechanize 获取请求 那么如何忽略这一点并继续连接到该网站呢 use IO Socket SSL qw use WWW Mechanize qw my mech WWW Mecha
  • 如何在 Perl 字符串中手动插入字符串转义符?

    在perl中假设我有一个像这样的字符串 hello tworld n 而我想要的是 hello world 也就是说 hello 然后是文字制表符 然后是 world 然后是文字换行符 或者等价地 hello tworld n 注意双引号
  • perl 和 java 正则表达式功能之间有什么区别?

    perl 和 java 在支持哪些正则表达式术语方面有什么区别 这个问题仅涉及正则表达式 并且特别排除了how可以使用正则表达式 即使用正则表达式的可用函数 方法 以及语言之间的语法差异 例如java要求转义反斜杠等 特别令人感兴趣的是 j
  • Perl 脚本的 shebang 行应该使用什么?

    哪一个用作 Perl 脚本的 shebang 行更好或更快 perl perl exe fullpath perl perl exe partialpath perl perl exe 并且 当使用 perl 当它在特定系统上运行时 我如何
  • Mojolicious:我应该使用一个还是多个 websocket?

    我正在自学 Mojolicious 和 websockets 到目前为止 我已经有了一个网页 它显示数据库中的行 并具有用于添加 删除和更新行以及选择用于排序的列的按钮 目前 它在每个按钮的 javascript onclick 处理程序中
  • 如何从 Perl 中的文本文件中提取/解析表格数据?

    我正在寻找类似的东西HTML 表格提取 http search cpan org dist HTML TableExtract 只是不适用于 HTML 输入 而是适用于包含采用缩进和间距格式化的 表格 的纯文本输入 数据可能如下所示 Her
  • 如何通过 sudo (或作为另一个用户)打开 Perl 文件句柄写入数据

    我想将数据写入文件 但应使用特定用户的访问权限打开文件句柄 因此 有以下声明 open FH gt filename or die n 将允许以该特定用户的身份写入文件 有没有办法在 Perl 脚本中执行此操作 而无需运行整个脚本sudo

随机推荐

  • lm.fit(x, y, offset = offset, Single.ok = Single.ok, ...) 中的错误 0 个非 na 情况

    我已经检查过有关此问题的其他问题 但由于问题似乎非常具体 因此它们没有帮助 我有一个像这样的数据框 这只是一个简单的示例 下面提供了来自 dput 的示例数据 year species abundance site county 2005
  • 如何将 Alt+空格发送到控制台窗口?

    import win32com client shell win32com client Dispatch WScript Shell shell AppActivate Command Prompt shell SendKeys This
  • c 中的全局键盘挂钩

    我想写一个全局键盘钩子来禁止任务切换 当我用谷歌搜索时 我发现了很多c cpp 和delphi 中的代码 但我需要一些关于钩子的基本概念 如果例子是C语言的 那将是最好的 所以 请建议可以帮助我从 C 角度理解事物的资源 链接 PS I f
  • 同一页面上有多个 Google CSE(自定义搜索引擎)框

    我正在尝试在同一页面上实现两个 不同的 Google CSE 搜索框 问题是只有第一个实例可以正常工作 例如 标题中的站点范围搜索框 然后在某些页面上 第二个搜索框在站点的狭窄筒仓内进行搜索 等等 这不能正常工作 因为使用谷歌为每个框生成的
  • 从txt文件中打印随机行?

    我使用 random randint 生成随机数 然后将该数字分配给变量 然后我想打印带有分配给变量的数字的行 但我不断收到错误 列表索引超出范围 这是我尝试过的 f open filename txt lines f readlines
  • 使用 bootstrap 3 垂直对齐中间内容

    我想使用最新的引导程序在 div 块中设置垂直中间内容v3 2 0 我已阅读答案与 bootstrap 3 垂直对齐 但它使用float none 在 div 块中 但是 我can t use float none 根据我们的布局在 div
  • 启用 SQL Server Express 2012 的远程连接

    我刚刚在我的家庭服务器上安装了 SQL Server Express 2012 我尝试从台式电脑上的 Visual Studio 2012 连接到它 并反复收到众所周知的错误 与 SQL Server 建立连接时发生与网络相关或特定于实例的
  • 如何在网站网址上隐藏我的网站端口号 [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我的网站是用JAVA实现的 所以我们采用了VPS并安装了Tomcat然后部署 我的网站是这样的 每当我点击 url 中的 www mysite com 时 它就会显示如下 http
  • 将 posix 样式时区转换为 c# .net 中的 timezoneinfo

    我从另一台机器获取时区信息 格式如下 CET 1CEST M3 5 0 2 M10 5 0 3 Posix 风格时区 我需要解析它并将其转换为c net TimeZoneInfo class 有办法实现这一点吗 根据这篇文章 http ww
  • 编辑 Google Storage 对象元数据需要哪些权限?

    我有以下 Perl 代码 response process gt request PATCH https www googleapis com storage v1 b Bucket o EscapedName content type i
  • Android 搜索活动未启动

    当我按下 Android 手机上的搜索按钮时 我的搜索框不显示 我想要做的是执行 ASyncTask 或后台任务 来获取字符串数组 人名 的 JSON 响应 搜索结果 并使用 IMDB 具有的相同搜索功能将其显示给用户 目前 我正在使用字符
  • 读取使用内联填充的 C# Textblock 文本属性

    假设我有一个空的 Textblock textblock1 Text 然后我只用这两条语句将内联内容放入其中 textblock1 Inlines Add new Run Text A Foreground Brushes Red text
  • switch case 中的默认值

    下面是我需要优化的代码 并计划最好转移到switch构造 但我可以比较case 所以我打算进行比较 len gt 3 作为default case 如果我将比较部分 len gt 3 作为默认情况并添加default作为switch中的第一
  • groupby DataFrame 按 N 列或 N 行

    我想找到一个通用的解决方案来按指定数量的行或列对 DataFrame 进行分组 示例数据框 df pd DataFrame 0 index a b c d e f columns c1 c2 c3 c4 c5 c6 c7 c1 c2 c3
  • Spring类路径前缀差异

    记录于4 7 2 2 类路径 前缀它指出 这个特殊的前缀指定所有 匹配的类路径资源 必须获得名字 在内部 这基本上发生 通过 ClassLoader getResources 调用 然后合并形成 最终应用程序上下文定义 有人可以解释一下吗
  • Tomcat:Web 应用程序中的自定义表单验证器,而不是作为独立的 JAR 模块。可能的?

    我们的 Web 应用程序需要内部具有特定逻辑的自定义表单身份验证 当前的表单验证器实现需要验证器模块 我们称之为custom auth jar 出现在 CATALINA HOME lib在 Web 应用程序启动之前 Web 应用程序使用该自
  • 使用 C# 从 Windows 服务捕获关键事件

    我必须用 C 编写一个应用程序来侦听按下的任何按键 实际上 我有一个条形码扫描仪发送 按键按下 事件 我需要听它 它的作用超出了我的问题范围 我的安全要求是不允许任何登录以任何形状或形式连接到机器并且这必须作为 Windows 服务运行 用
  • 查找最长的重复字符串及其在给定字符串中的重复次数

    例如 给定字符串 abc fghi bc kl abcd lkm abcdefg 该函数应返回字符串 abcd 以及 2 的计数 O n 2 解决方案似乎很简单 但我正在寻找更好的解决方案 Edited 如果不可能有比 O n 2 更好的方
  • 量词中的非零向量

    我想验证以下形式的公式 Exists p ForAll x 0 f x p gt 0 一个实现 不起作用 如下 def f0 x0 x1 x y return x1 2 y x0 2 x s Solver x0 x1 Reals x0 x1
  • 从大型固定宽度文本中解析未排序的数据

    我主要是一个 Matlab 用户和 Perl n00b 这是我的第一个 Perl 脚本 我有一个大型固定宽度数据文件 我想将其处理成带有目录的二进制文件 我的问题是数据文件非常大 并且数据参数按时间排序 这使得解析到 Matlab 变得困难