在bash / perl中解析文本文件的有效方法

时间:2014-11-06 22:52:51

标签: bash perl awk sed

我有大量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>
 ...

2 个答案:

答案 0 :(得分:1)

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

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

可以&#34;打高尔夫球&#34;如果你喜欢那种东西,可以使用更简洁的单行内容。

答案 1 :(得分:1)

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

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