2014-11-06 33 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 }