2014-11-06 70 views
2

我有大量300k +行的文本文件。在bash/perl中解析txt文件的有效方法

的文件是在常规格式:

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> 
... 
+0

是否有'<多个报头文本>固定数量的' “用户名”行和你想匹配的行之间的连线?你是否也可以包含一些示例数据以匹配什么和不匹配什么? – 2014-11-06 23:10:07

+0

我做了一个小小的编辑 - 让我们假设只有一个标题行,匹配的字符串真的没关系......知道它匹配一些'$ string' – user3979986 2014-11-06 23:13:03

+0

@ user3979986:这很朦胧!如果紧随其后的行匹配任何'$ string',你就想打印'user'和'file'字段。意味着任何随机字符串的任多么奇怪。 – Borodin 2014-11-07 00:13:39

回答

1

对于这样的真重文本处理,Perl是一种不错的选择:

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

这可以被“golfed”下调至一个更简洁的单行,如果你喜欢那样的事情。

1

awk中溶液,依靠每个记录是两行(和该文件是用于所述第一记录头的第一个行):

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