shifting decimal point using vim, shell or python

  • A+
Category:Languages

I have a .pl file that consists of an unstructured header and some specific X Y Z structure. The header has no "." in there. Below you can find a snippet of this file:

Header (in total 29 lines) ILINE VRTX 1 545057.78564453125 3800905.201171875 -15000  VRTX 2 545184.49072265625 3800765.451171875 -15000  VRTX 3 545310.91650390625 3800625.970703125 -15000  SEG 1 2  SEG 2 3  ILINE VRTX 136 551295.84606933594 3799015.443359375 -15000  VRTX 137 551293.82849121094 3798841.880859375 -15000  VRTX 138 551290.57849121094 3798661.892578125 -15000   SEG 136 137  SEG 137 138  

What I like to achieve is to shift the decimal point of my X and Y values to the left like this:

VRTX 1 5450.5778564453125 38009.05201171875 -15000  VRTX 2 5451.8449072265625 38007.65451171875 -15000  VRTX 3 5453.1091650390625 38006.25970703125 -15000 

I think that regular expressions could help but I have no experiences in that using Python nor Shell. Any help is appreciated.

 


Since there is a vim tag on the question:

//. qaqqanx2hi!<esc>@aq @a :%s/!/./g 

Assuming there is no ! in the text, else you have to substitute it with a different character(s). Of course there are other solutions in vim, but that's the simplest which I can think of right now.

Breakdown:

 //.                  " searches every `.` in the file                        " (and "marks" them as searchresults)  qaqqanx2hi!<esc>@aq   " Our macro we use: qaq                   " records an empty macro into register a                        " (This ensures the register is empty)    qa                 " This starts recording a macro into register a again      nx2hi!<esc>      " `n` jumps to the next search result,                         " `2hxhi!<esc>` inserts a `!` 2 chars left of where                       " the `.` has been, and exits insert mode                 @a    " calls the macro at register `a`, since we emptied it,                       " nothing happens yet, but once we save this macro it will                       " be in register `a`. So it will call itself until it                        " reaches an abort conditions (no more `.` found in the                       " text, thats why we replace `.` with `!` here, else                       " the macro would move the `.` over and over to the left                   q   " Stops recording the macro and saves it (to register `a`)  @a                    " calls the macro in register `a`  :%s/!/./g             " This just replaces all `!` in the file with `.` 

Possible cleaner solution: Use nowrapscan (thanks @Francesco)

//. :set nows qaqqax3hpn@aq @a :set ws 

Note: The Macro changes order a bit. We must first change the position of the . and then jump to the next search-occurence else we will miss the first occurence, since the search doesn't wrap arround eof anymore.

Note: It would be better to save the state of ws before and then restore it. But that would only matter in a generic version.

Conclusion

Complicated but flexible solution. If you don't need to be flexible, the other vim solutions here are easier (I will not judge other solutions)

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: