2012-07-26 72 views
3

我已經在多個文本文件看起來像這樣的數據:過濾多pcregrep匹配的sed

1 DAEJ    X   -3120041.6620  -3120042.0476  -0.3856  0.0014    
        Y    4084614.2137  4084614.6871  0.4734  0.0015    
        Z    3764026.4954  3764026.7346  0.2392  0.0014    

        HEIGHT   116.0088   116.6419  0.6332  0.0017  0.0017 8.0 
        LATITUDE  36 23 57.946407 36 23 57.940907 -0.1699  0.0013  0.0012 57.5  0.0012 62.9 
        LONGITUDE 127 22 28.131395 127 22 28.132160 0.0190  0.0012  0.0013 2.3  0.0013 

,我想通過一個過濾器來運行它,以便輸出將是這樣的:

DAEJ: 36 23 57.940907, 127 22 28.132160, 116.6419 

(?<site>\w\w\w\w+)<filler>\r\n\r\n<filler>(?<height>\-?\d+\.\d+)<filler>(?<heightRMS>\d+\.\d+)<filler>\r\n<filler>(?<lat>\-?\ *\d+\ +\d+\ +\d+\.\d+)<filler>(?<latRMS>\d+\.\d+)<filler>\r\n<filler>(?<lon>\-?\ *\d+\ +\d+\ +\d+\.\d+)<filler>(?<lonRMS>\d+\.\d+)<filler> 

與repacing(:

我可以grepWin使用命名捕獲通過搜索做到這一點很容易不夠忽略未被引用的組,我會在其他實現中使用它):

$+{site}: $+{lat}, $+{lon}, $+{height} 

但當然,以通過GUI手動執行操作爲代價。我想知道是否有辦法通過管道pcregrep輸出到sed進行文本替換來編寫腳本?我知道pcregrep -M選項匹配上面的多行正則表達式模式,並且我已經成功,直到那一點,但我堅持sed結束的問題。

+0

我知道我可以通過'\ 9'而不是命名捕獲來使用'\ 1'的反向引用,但是我選擇後者作爲優先事項。 – alfie 2012-07-26 06:02:44

+0

在steve下面的出色答案後,我意識到我仍然需要在LATITUDE/LONGITUDE數據行中奇怪格式化的負值情況下捕獲可能的減號,例如' - 6 29 27.798898'。 – alfie 2012-07-26 09:15:00

回答

3

我將使用awk來處理文本文件:

awk '$1 ~ /^[0-9]+$/ { printf "%s: ", $2 } $1 == "HEIGHT" { height = $3 } $1 == "LATITUDE" { printf "%s %s %s, ", $2, $3, $4 } $1 == "LONGITUDE" { printf "%s %s %s, %s\n", $5, $6, $7, height }' file.txt 

多條線路上爆發了可讀性:

$1 ~ /^[0-9]+$/ { 
    printf "%s: ", $2 
} 

$1 == "HEIGHT" { 
    height = $3 
} 

$1 == "LATITUDE" { 
    printf "%s %s %s, ", $2, $3, $4 
} 

$1 == "LONGITUDE" { 
    printf "%s %s %s, %s\n", $5, $6, $7, height 
} 

結果:

DAEJ: 36 23 57.946407, 127 22 28.132160, 116.6419 

編輯:

將下面的代碼在名爲script.awk文件:

$3 == "X" { 
    printf "%s: ", $2 
} 

$1 == "HEIGHT" { 
    height = $3 
} 

$1 == "LATITUDE" { 
    if ($2 == "-" && $6 == "-") { printf "-%s %s %s, ", $7, $8, $9 } 
    else if ($2 == "-") { printf "%s %s %s, ", $6, $7, $8 } 
    else if ($5 == "-") { printf "-%s %s %s, ", $6, $7, $8 } 
    else { printf "%s %s %s, ", $5, $6, $7 } 
} 

$1 == "LONGITUDE" { 
    if ($2 == "-" && $6 == "-") { printf "-%s %s %s, %s\n", $7, $8, $9, height } 
    else if ($2 == "-") { printf "%s %s %s, %s\n", $6, $7, $8, height } 
    else if ($5 == "-") { printf "-%s %s %s, %s\n", $6, $7, $8, height } 
    else { printf "%s %s %s, %s\n", $5, $6, $7, height } 
} 

像這樣運行:

awk -f script.awk file.txt 
+0

謝謝!這使我更接近解決方案,做了以下修改:'awk'$ 3 ==「X」{printf「%s:」,$ 2} $ 1 ==「HEIGHT」{height = $ 3} $ 1 ==「 LATITUDE「{printf」%s%s%s「,$ 5,$ 6,$ 7} $ 1 ==」LONGITUDE「{printf」%s%s%s,%s \ n「,$ 5,$ 6,$ 7,height} 'file.txt'現在,我需要進一步修改_that_以允許Lat/Lon的負DMS值,即'\ - ?\ * \ d + \ + \ d + \ + \ d + \。\ d +'正則表達式模式,其中可能的減號可能會或可能不會與第一個整數值相隔一個空格。 – alfie 2012-07-26 09:02:19

+0

我可以做'awk'$ 3 ==「X」{printf「%s:」,$ 2} $ 1 ==「HEIGHT」{height = $ 3} $ 1 ==「LATITUDE」{printf(($ 2 ==「 - 「)?」%s%s%s%s「,$ 6,$ 7,$ 8,$ 9:」%s%s%s「,$ 5,$ 6,$ 7)} $ 1 ==」LONGITUDE「{printf ($ 2 ==「 - 」)?「%s%s%s%s,%s \ n」,$ 6,$ 7,$ 8,$ 9,height:「%s%s%s,%s \ n」, $ 5,$ 6,$ 7,height)}''首先測試是否存在減號? – alfie 2012-07-26 10:43:12

+0

@alfie,我會告訴你一個'if else'塊,給我一分鐘左右 – Steve 2012-07-26 11:00:30

0

這可能爲你工作(GNU SED):

sed '/^DAEJ/,/^\s*LONGITUDE/!d;/HEIGHT/{s/^\s*\S*\s*\S*\s*\(\S*\).*/\1/;h};/LATITUDE/{s/^\s*\(\S*\s*\)\{4\}\(\(\S*\s*\)\{2\}\S*\).*/\2/;H};/LONGITUDE/!d;s/^\s*\(\S*\s*\)\{4\}\(\(\S*\s*\)\{2\}\S*\).*/ \2/;H;g;y/\n/,/;s/\([^,]*\),\(.*\)/DAEJ: \2, \1/' file1 file2 filen