2017-10-11 59 views
-1

我正在尋找一些我一直在研究的東西的指導。我試圖將三種不同格式的數據轉換爲格式化數據。使用VIM從A轉換爲B

這是我需要轉換數據:

ABCDEFGHIJKL  00100  C     N12345678W1234567891234  GND 99999MMY LITTLE TEST    000000000 
ABCDEFGHIJKL  00100  H N12345678W123456789        GND 99999MANOTHER LITTLE TEST   000000000 
ABCDEFGHIJKL  00200  L N12345678W123456789N12345678W12345678912341234            000000000 
ABCDEFGHIJKL  00300  G N12345678W123456789                  000000000 

這是輸出,我想:

map <Insert> :%s/...................................................$/<ESC> :%s/....................//<ESC> :%s/0  G /\|G\|/e<ESC> :%s/0  C /\|C\|/e<ESC> :%s/0  H /\|H\|/e<ESC> :%s/0  L /\|L\|/e<ESC> :%s/0  R /\|R\|/e<ESC> :%s/e0/\|E0/ge<ESC> :%s/w0/\|W0/ge<ESC> :%s/w1/\|W1/ge<ESC> :%s/ /\|\|<ESC> :%s/e1/\|E1/ge<ESC> :%s/    //e<ESC>:%s/\s\+$//<ESC> :%s#\d\{4}$#\=printf('\|%.1f', str2nr(submatch(0))/10.0)#e<ESC> 

0010|C|||N12345678|W123456789|123.4 
0010|H|N12345678|W123456789|| 
0020|L|N12345678|W123456789|N12345678|W123456789|123.4|123.4 
0030|G|N12345678|W123456789| 

我與映射插入按鈕我正在轉換,但有一點侷限性,因爲我得到以下內容:

0010|C|||N12345678|W123456789|123.4 
0010|H|N12345678|W123456789|| 
0020|L|N12345678|W123456789N12345678|W1234567891234|123.4 
0030|G|N12345678|W123456789|| 

前四位數字之後的字母可以是G,C,H,L或R,因此代碼作出考慮。 12345678的字母是羅盤方向,因此可以是N,S,E或W.

我的代碼問題是如果我使用find和replace將N更改爲||它發現的第一個N之前。也| |和小數時,有一個弧形繪製,並且是和L或R.

任何幫助將不勝感激。

編輯:

獲取月底去掉多餘的字符:

:%s/...................................................$/<ESC> 

獲取在開始擺脫多餘的字符:

:%s/....................//<ESC> 

擺脫多餘的空間,並增加了一個|正面和後面的首字母:

:%s/0  G /\|G\|/e<ESC> 

獲取擺脫多餘的空格並添加|正面和後面的首字母:

:%s/0  C /\|C\|/e<ESC> 

刪除多餘的空格並添加|正面和後面的首字母:

:%s/0  H /\|H\|/e<ESC> 

獲取擺脫多餘的空格並添加|正面和後面的首字母:

:%s/0  L /\|L\|/e<ESC> 

刪除多餘的空格並添加|前面和後面的首字母:

:%s/0  R /\|R\|/e<ESC> 

添加|座標方向的指南針方向

:%s/e0/\|E0/ge<ESC> 

添加|座標方向的指南針方向

:%s/w0/\|W0/ge<ESC> 

添加|羅盤方向的盈爲座標

:%s/w1/\|W1/ge<ESC> 

再添||用於處理單套座標時

:%s/ /\|\|<ESC> 

添加|盈方羅盤方向的座標

:%s/e1/\|E1/ge<ESC> 

不wuite知道爲什麼我把這個在:

:%s/    //e<ESC> 

擺脫任何空格和尾隨字符:

:%s/\s\+$//<ESC> 

繪製時使用L或R使用C或弧形圈,然後將末端數字轉換爲十進制並添加|盈分開它:

:%s#\d\{4}$#\=printf('\|%.1f', str2nr(submatch(0))/10.0)#e<ESC> 
+2

使用awk會更容易... – Kent

+2

請分解您的映射,將其分成多行,並告訴我們每條線(您認爲)是什麼。另外,爲什麼你用''而不是''結束每個命令? –

+0

我添加了已經創建的映射關鍵代碼的分解,我需要弄清楚在處理以L或R開頭的序列時如何轉換第一批小數。另一個問題是我無法獲得|在額外的座標前面提出了這個問題::%s/L ..................... N/........ .............. \ | N/e 但是,這取代它與點任何想法如何使用點作爲任何字符,所以我代替我需要的? – Moneyboi

回答

0

我會建議使用gawk(GNU AWK)。您可以使用FIELDWIDTH變量來設置由空格分隔的每個字段的寬度。

gawk 'BEGIN{FIELDWIDTHS="12 8 5 5 1 1 9 10 9 10 4 4"; OFS="|"} { for(i=1;i<=NF;i++) { gsub(/^[ \t]+|[ \t]+$/, "", $i); }; x=""; if ($11) { x = $11/10;} y=""; if ($12) { x = $12/10;} print $3, $5, $7, $8, $9, $10, x, y; }' file.txt 

更多人類可讀的:

BEGIN { 
     FIELDWIDTHS="12 8 5 5 1 1 9 10 9 10 4 4"; 
     OFS="|" 
} 

{ 
     for (i=1;i<=NF;i++) { 
       gsub(/^[ \t]+|[ \t]+$/, "", $i); 
     } 
     x=""; 
     if ($11) { 
       x = $11/10; 
     } 
     y=""; 
     if ($12) { 
       y = $12/10; 
     } 
     print $3, $5, $7, $8, $9, $10, x, y; 
} 

注:這是一個稍微不同的輸出格式,你所付出的。

您可以使用filter命令:!來進行映射。

相關問題