使用VIM从A转换为B.

时间:2017-10-11 09:17:39

标签: vim

我正在寻找关于我一直在努力的事情的一些指导。我试图将三种不同格式的数据转换为格式化数据。

这是我需要转换的数据:

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

这是我想要的输出:

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

我已将插入按钮映射为:

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|W123456789N12345678|W1234567891234|123.4
0030|G|N12345678|W123456789||

前四位数字后面的字母可以是G,C,H,L或R,因此我们制作的代码会考虑到这一点。 12345678前面的字母是罗盘方向,因此可以是N,S,E或W.

我的代码问题是,如果我使用find和replace将N更改为N,那么它将替换all并添加两个||在它找到的第一个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>

不确定为什么我把它放进去:

:%s/               //e<ESC>

删除任何空格和尾随字符:

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

使用L / R使用C或弧绘制圆形时,它会将结束数字转换为十进制并添加|面前将它分开:

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

1 个答案:

答案 0 :(得分:0)

我建议使用App extends MultiDexApplication (GNU awk)。您可以使用gawk变量来设置用空格分隔的每个字段的宽度。

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; } 进行映射。