2011-05-23 24 views
2

我需要通過將每行分割成4段並插入分隔符(如管道或:in each segment)來重建文件。我的問題是,結構有些不一致......bash/regex用於使用複雜模式重建部分不一致的文件

文件看起來是這樣的:

MIKE TESTUSER Some Text 21 - Etc BLA 43 BLA - Some, Additional..12 info 

STEVE NOBODY 43 More `Text and So on BLA (MORE ADDITIONAL info) 

LEROY ANYONE Again some text chars numbers BLABLA 

,我需要把它拆分成名稱:地址:城市和可選的Zip:可選的附加信息

MIKE TESTUSER|Some Text 21 - Etc|BLA43 BLA|- Some, Additional..12 info 

STEVE NOBODY|43 More `Text and So on|BLA|(MORE ADDITIONAL info) 

LEROY ANYONE|Again some text chars, numbers|BLABLA 

第一段永遠是大寫的,沒有數字或特殊字符 第二段由任何東西,除了單詞大寫 第三部分是隻有大寫字母,有時數 最後一段可以是除大寫的話有沒有

將是巨大的,如果有人有一個解決方案或者可以點我到是讓我接近一個方向(沒有按」 t必須完美)


首先感謝您的快速回復!我試圖用空白將每行分解爲數組元素,然後檢查每個元素的大小寫,數字等等,有點像chard awk方法。問題在於,由於段有時以數字或非字母數字字符結尾,而下一段以數字/非字母數字字符開始,因此我無法始終確定何時必須放置分隔符。

例如

這個名字23街達蓋爾321 12345馬賽 - 信息

應該像

這個名字| 23街達蓋爾321 | 12345 |馬賽 - 信息

該文件有幾千行,非常麻煩。經常郵政編碼 來自於城市的前面,有時加上其他各種矛盾背後..

我知道我必須在任何情況下手動重新編輯,但我希望能找到一個解決方案, 品牌它並不是所有的時間:)

+0

你嘗試過這麼遠嗎?我們不應該從頭開始爲你寫這篇文章:-) – 2011-05-23 17:19:45

+0

你的規則有一個含糊之處:在你的最後一個例子中,第二個分隔符可以在'321'之前或在'12345'之後。 – Beta 2011-05-24 22:47:14

回答

2

它必須只是bash?我會認真考慮寫一些簡單的Awk程序。

說,作爲一個開始

awk -f 'BEGIN {FS=" "; uplow=0;} 
       {uplow=1; 
       for(i=1; i < $NF; i++){ 
        if(uplow && ($i ~ [A-Z])) out += $i+" " 
        else if (uplow && ($i !~ [A-Z])) { 
         uplow = 0; 
         out += "|" 
        } else if # fill in the other cases 
       } 
       print out 
       }' 

的想法是檢查每個空白分隔的字段的情況下,並保持標誌記住,如果你在大寫的物品或小寫的運行是項目。你改變了什麼,把你的管道字符添加到輸出中。

+0

在這一點上任何解決方案將不勝感激 – qbitz28 2011-05-23 17:18:09

1

你真的需要一個像Perl一樣的完整語言。它會是這樣的:

use strict; 
use warnings; 

open MY_FILE "myFileName" or die qq(Can't open "myFileName" for reading\n); 
while (my $line = <MY_FILE>) { 
    chomp $line; 
    $line =~ /([A-Z\s]+)(.*)([A-Z\d\s]{2,})(.*); 
    print join "|", ($1, $2, $3, $4) . "\n"; 
} 

的大招是在正則表達式:

$line =~ /([A-Z\s]+)(.*)([A-Z\d\s])(.*); 

那就是打破了線分爲四個部分(然後由$1通過$4代表)。我沒有足夠的數據來開始測試它。

你可以給你的問題附上大約4到5行的文件,我會解決一些問題嗎?

0

這可能會爲你工作:

sed 's/^\([A-Z ]*\) \(.*\)/\2\n\1|/;s/[A-Z]\{2\}/|&/;s/\([^|]*|\)\(.*\)/\2\1/;s/\([^A-Z0-9 ]\)/|\1/;s/\([^\n]*\)\n\(.*\)/\2\1/;s/|$//' file