2017-10-11 56 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命令:!来进行映射。

相关问题