我有一个.pl文件,其中包含非结构化标头和某些特定的X Y Z结构。标头中没有“。”。在那里。您可以在下面找到此文件的摘要:
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
我想要实现的是这样将X和Y值的小数点向左移动:
VRTX 1 5450.5778564453125 38009.05201171875 -15000
VRTX 2 5451.8449072265625 38007.65451171875 -15000
VRTX 3 5453.1091650390625 38006.25970703125 -15000
我认为正则表达式可能会有所帮助,但是我没有使用Python或Shell的经验。任何帮助表示赞赏。
答案 0 :(得分:5)
复制和粘贴友好的vim解决方案
:g/VRTX/normal f.xhhP;xhhP
说明:
答案 1 :(得分:2)
您可以使用awk
来执行此操作,这是单行命令,
awk '{for(i=1;i<=NF;i++)if(match($i,/[0-9][0-9]\./))$i=substr($i,0,RSTART-1)"."substr($i,RSTART,2)substr($i,RSTART+3)}1' input_file
简要说明,
match($i,/[0-9][0-9]\./
:检查是否有任何字段与正则表达式[0-9][0-9]\.
匹配awk
会在RSTART
中记录匹配案例的起点。我们可以使用substr
函数和RSTART
信息来重新生成文件,以满足您的要求。答案 2 :(得分:2)
由于该问题上有一个vim标签:
/\.
qaqqanx2hi!<esc>@aq
@a
:%s/!/./g
假设文本中没有!
,否则您必须用其他字符代替。当然,vim中还有其他解决方案,但这是我现在能想到的最简单的方法。
故障:
/\. " 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 `.`
可能的清洁解决方案:使用nowrapscan (感谢@Francesco)
/\.
:set nows
qaqqax3hpn@aq
@a
:set ws
注意:宏更改顺序有点。我们必须首先更改.
的位置,然后跳转到下一个搜索出现位置,否则我们将错过第一次出现的位置,因为搜索不再包含所有内容。
注意:最好先保存ws
的状态,然后再将其还原。但这仅在通用版本中很重要。
结论
复杂但灵活的解决方案。如果您不需要灵活,这里的其他vim解决方案会更容易(我不会判断其他解决方案)
答案 3 :(得分:1)
这是Python中的解决方案。首先,我们定义一个为我们移动小数的函数。
SEARCH = '.'
OFFSET = -2
def replacer(bits):
if SEARCH in bits:
loc = bits.index(SEARCH)+OFFSET
return ''.join('{}.'.format(x) if k == loc-1 else x for k,x in enumerate(bits.replace('.','')))
else:
return bits
下一步,将其应用于行:
s = """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"""
>>> for i in s.split('\n'):
.. if i.startswith('VRTX'):
.. print(' '.join(map(replacer, i.split(' '))))
VRTX 1 5450.5778564453125 38009.05201171875 -15000
VRTX 2 5451.8449072265625 38007.65451171875 -15000
VRTX 3 5453.1091650390625 38006.25970703125 -15000
VRTX 136 5512.9584606933594 37990.15443359375 -15000
VRTX 137 5512.9382849121094 37988.41880859375 -15000
VRTX 138 5512.9057849121094 37986.61892578125 -15000
答案 4 :(得分:1)
我的正则表达式解决方案
:%s,\v(\d\d)\.,.\1,g
\v ...... very magic to avoid many backslashes
(\d\d) .. regex group one
\. ...... literal dot
\1 ...... reference to regex group one
答案 5 :(得分:0)
import re
new_data = ''
for line in data.splitlines():
if '.' in line:
mod_line = ''
for word in line.split():
if '.' in word:
try:
float(word)
word = re.sub(r'(\d\d)\.', r'.\1', word)
except:
pass
mod_line += word + ' '
new_data += mod_line.rstrip() +'\n'
else:
new_data += line + '\n'
new_data = new_data.rstrip()
print (new_data)
输出
ILINE
VRTX 1 5450.5778564453125 38009.05201171875 -15000
VRTX 2 5451.8449072265625 38007.65451171875 -15000
VRTX 3 5453.1091650390625 38006.25970703125 -15000
SEG 1 2
SEG 2 3
ILINE
VRTX 136 5512.9584606933594 37990.15443359375 -15000
VRTX 137 5512.9382849121094 37988.41880859375 -15000
VRTX 138 5512.9057849121094 37986.61892578125 -15000
SEG 136 137
SEG 137 138