前言
因爲工作的需求經常需要把一些文本模式的字符串轉爲指定的格式,如:
json格式化
時間戳轉時間
時間轉時間戳
生成時間字符串
每次都需要連網使用一些在線小工作,但是好多時間又需要斷開Internat只連內網,
經常用Vim,Vim如此強大能不能直接在Vim裏實現呢?
環境:
操作系統:Windows10
Python:3.6.8
Vim:8.1
第一步:需求
- 可以把unicode編碼的json文本轉爲標準json
- 可以把utf-8未解碼的json轉爲標準json
- 把時間轉爲時間戳
- 把時間戳轉是標準時間,例:2019-12-31 12:00:00
第二步:python實現
fs.py代碼:
# -*- coding: utf-8 -*-
import argparse
import collections
import datetime
import json
import sys
import time
def parse_datetime(str_time=None, fmt='%Y-%m-%d %H:%M:%S'):
"""
將時間字符串解析爲時間
:param str_time:
:param fmt:
:return:
"""
t = datetime.datetime.now()
if str_time:
try:
t = datetime.datetime.strptime(str_time, fmt)
except:
try:
t = datetime.datetime.strptime(str_time, '%Y/%m/%d %H:%M:%S')
except:
try:
# UTC時間轉爲北京時間需要加上8小時時差
t = datetime.datetime.strptime(str_time, '%Y-%m-%dT%H:%M:%SZ')
t += datetime.timedelta(hours=8)
except:
try:
# UTC時間轉爲北京時間需要加上8小時時差
t = datetime.datetime.strptime(str_time, '%Y-%m-%dT%H:%M:%S.%fZ')
t += datetime.timedelta(hours=8)
except Exception as e:
t = t
return t
def str_to_timestamp(str_time=None, fmt='%Y-%m-%d %H:%M:%S'):
"""時間轉時間戳"""
str_time = str(str_time)
convert_timestamp = str_time
if str_time:
if str_time.isdigit():
if len(str_time) == 10:
convert_timestamp = int(str_time)
else:
convert_timestamp = int(str_time) / 1000
else:
d = parse_datetime(str_time, fmt)
convert_timestamp = int(time.mktime(d.timetuple()))
return convert_timestamp
def timestamp2str(ts, fmt='%Y-%m-%d %H:%M:%S'):
ts = str(ts)
convert_str = ts
if ts.isdigit():
ts = int(ts[0:11])
convert_str = time.strftime(fmt, time.localtime(ts))
return convert_str
def main():
parser = argparse.ArgumentParser()
parser.add_argument('infile', nargs='?', type=argparse.FileType())
parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'))
options = parser.parse_args()
infile = options.infile or sys.stdin
outfile = options.outfile or sys.stdout
with infile:
try:
content = infile.read()
# 轉義未解碼的utf-8
if "\\x" in content:
content = content.replace("'", "\"")\
.replace("\r\n","")\
.replace("\n","")\
.replace("\r","")
content = eval("b'" + content + "'").decode('utf8')
obj = json.loads(content, object_pairs_hook=collections.OrderedDict)
except Exception as e:
raise SystemExit(e)
try:
# unicode
if "\\u" in content:
obj = json.loads("u'" + content.strip() + "'")
else:
# 時間
obj = str(str_to_timestamp(content))
except:
obj = content
# 時間戳轉時間
if isinstance(obj, int):
obj = timestamp2str(int(content))
# raise SystemExit(e)
with outfile:
if isinstance(obj, dict) or isinstance(obj, list):
json.dump(
obj,
outfile,
indent=4,
ensure_ascii=False
)
outfile.write('\n')
elif isinstance(obj, str) or isinstance(obj, int):
outfile.write(str(obj))
outfile.write('\n')
if __name__ == '__main__':
main()
測試數據:
數據1:
{"shanghai": "\u4e0a\u6d77", "zhengzhou": "\u90d1\u5dde"}
數據2:
{'shanghai': '\xe4\xb8\x8a\xe6\xb5\xb7', 'zhengzhou': '\xe9\x83\x91\xe5\xb7\x9e'}
數據3:
1577793600
數據4:
2019-12-31 18:13:39
將該數據放在一個文本中然後以該文本文件的名稱如(test)作爲參數
第三步:將該Python腳本加入到sys根目錄下
wedo.pth內容:
D:\Workspace\Github\myconf\vim\cmd\python
上面的路徑是fs.py路徑所在位置
然後把該文件放在site-packages目錄下,甚至具體哪個目錄不同的環境目錄也不同,自己找吧
如還是不知道,可以用如下腳本打印一下:
import site;
print(site.getsitepackages())
執行命令如下:
python -m fs test
第四步:在vim配置文件中添加相關配置
command! FS :execute ‘%!python -m fs’
它的意思是在vim的ex模式下輸入FS會調用我們的Python腳本
第五步:使用
OK這個時候就可以把打開Vim把需要的文本格式化爲任意想要的格式了,命令如下:
:FS
總結
雖然這樣可以目標實現了,但是目前爲止還是有缺陷的:
文本文件中全部的內容必須是要格式化的文本,否則的話會報錯
一個不那麼友好的解決方式是先選中指定的文本,然後直接調用python而不是指定的命令:
:!python -m fs
中間的’<,’>這個不用管,它代表上面你選中的內容,當你選中之後按冒號(:)會自動出現的
有更好的實現方式歡迎指正哈