Vim調用外部python腳本將文本格式化任意模式(json/時間/時間戳)

前言

因爲工作的需求經常需要把一些文本模式的字符串轉爲指定的格式,如:
json格式化
時間戳轉時間
時間轉時間戳
生成時間字符串
每次都需要連網使用一些在線小工作,但是好多時間又需要斷開Internat只連內網,
經常用Vim,Vim如此強大能不能直接在Vim裏實現呢?

環境:

操作系統:Windows10
Python:3.6.8
Vim:8.1

第一步:需求

  1. 可以把unicode編碼的json文本轉爲標準json
  2. 可以把utf-8未解碼的json轉爲標準json
  3. 把時間轉爲時間戳
  4. 把時間戳轉是標準時間,例: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

中間的’<,’>這個不用管,它代表上面你選中的內容,當你選中之後按冒號(:)會自動出現的
在這裏插入圖片描述在這裏插入圖片描述

有更好的實現方式歡迎指正哈

發佈了96 篇原創文章 · 獲贊 201 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章