【问题标题】:Efficient way to parse txt file in bash/perl在 bash/perl 中解析 txt 文件的有效方法
【发布时间】:2014-11-06 22:52:51
【问题描述】:

我有无数大小超过 300k 行的文本文件。

文件采用以下通用格式:

Username <user> filename <file>
<some large amount of text on one line>
...

文本文件具有这种严格的格式——一行格式化的标题文本,然后是一行非常长的行,这是文件的主要内容。

我想要做的是浏览文件并为每一组行(由标题和一行组成的一组)在这个长行中查找一些匹配的字符串。

如果字符串在那里,那么我想打印userfile。如果没有,那么我们继续,不打印任何东西。对于那些会问的人,这个练习的目的只是把它打印出来,然后我会在以后做一些操作。

我知道如何做到这一点,但这是一种蛮力 - 只需在检测到用户和文件时存储它们,如果我们检测到匹配的字符串,我们会打印 userfile。如果没有,请继续。但是,这是非常低效的:

#!/usr/bin/sh
##not exact, just roughly what i am doing
while read line; do
if [[ $line =~ Username ([^ ]+) filename ([^ ]+) ]];then
    #store our variables
    continue
fi
if [[ $line =~ "string" ]];then
     #print user and file
fi
done < inputfile

基本上,是否有一些有效的方法来检测我正在寻找的字符串,然后回顾 x 行数(x 对应于标题行数),然后提取我需要的信息? 谢谢

PS 在 bash-perl 中做这件事并不那么好。

编辑:期望的输出

 <user>, <file>
 <user>, <file>
 ...

【问题讨论】:

  • Username 行和要匹配的行之间是否存在固定数量的&lt;more header text&gt; 行?您能否还包括一些匹配和不匹配的示例数据?
  • 我做了一个小编辑——让我们假设只有一个标题行,匹配的字符串真的无关紧要......重要的是要知道它匹配一些$string跨度>
  • @user3979986:这很模糊!如果紧随其后的行与任何 $string 匹配,您想要打印 userfile 字段。意味着任何地方的任何随机字符串?多么奇怪。
  • 解释这一点的方法是给出一个简短的输入示例,其中包括一些打印的userfile 值和一些不打印的值。即使是您的 shell 脚本的完整工作版本也会有很大帮助。
  • 任何时候你在 shell 中编写一个循环只是为了转换文本你有错误的方法。显示一些实际的示例输入,而不仅仅是输入格式的描述,以及给定输入的所需输出。而且您的示例输入行不需要“非常长”来证明您的问题。

标签: bash perl awk sed


【解决方案1】:

对于像这样非常繁重的文本处理,perl 是一个不错的选择:

perl -nE '
  if ($. % 2 == 1) {
    ($user, $file) = (split ' ')[1,3];
  } 
  elsif (/search string/) {
    say "$user, $file";
  }
' file1 file2 ...

如果你喜欢那种东西,那可以“打高尔夫球”到更简洁的单线。

【讨论】:

    【解决方案2】:

    awk 解决方案,依赖于每条记录为两行(文件的第一行为第一条记录的标题):

    NR%2 { name = $2; file =$4; next }
    /string/ { print name, file }
    

    【讨论】:

      猜你喜欢
      • 2018-12-31
      • 2012-05-28
      • 1970-01-01
      • 2016-10-18
      • 2019-03-11
      • 2010-12-16
      • 1970-01-01
      相关资源
      最近更新 更多