vieyahn2017 / shellv

shell command test and study
4 stars 1 forks source link

python实现sed #96

Open vieyahn2017 opened 3 months ago

vieyahn2017 commented 3 months ago

初稿来自 https://blog.csdn.net/zhulinxiaoan/article/details/106344821

vieyahn2017 commented 3 months ago

import argparse
import re
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--expr", help="expression")
    parser.add_argument("filename", type=str)
    return parser.parse_args()

def match_file(old_expr, new_expr, file, cout):
    with open(file, 'r', encoding='utf-8') as f:
        for line in f.readlines():
            result = re.sub(old_expr, new_expr, line, count=cout)
            print(result, end='')

def read_file(filename1, filename2):
    with open(filename1, 'r', encoding='utf-8') as f1:
        for line1 in f1:
            print(line1.strip())
            with open(filename2, 'r', encoding='utf-8') as f2:
                for line2 in f2:
                    print(line2.strip())

def sed_func(args):

    if args.expr.split('/')[0] == 's' and \
            args.expr.split('/')[-1] == 'g':
        match_file(args.expr.split('/')[1], args.expr.split('/')[2],
                   args.filename, cout=0)
    elif args.expr.split('/')[0] == 's' and \
            args.expr.split('/')[-1] != 'g':
        match_file(args.expr.split('/')[1], args.expr.split('/')[2],
                   args.filename, cout=1)
    elif args.expr.split()[0] == 'r':
        read_file(args.filename, args.expr.split()[1])

args = parse_args()
sed_func(args)
vieyahn2017 commented 3 months ago
### usage:
# python sed.py -e "s/5月 [0-9][0-9]/DATE/g" 123.txt
# python sed.py -e "s/5月 [0-9][0-9]/DATE/" 123.txt
# python sed.py -e "s/admin/moon/g" 123.txt
# python sed.py -e "s/admin/moon/" 123.txt

#python sed.py  -e  'r 123.data'  123.txt 

最后一个我觉得没啥用?

vieyahn2017 commented 3 months ago

测了下sed

sed --help
  -i[SUFFIX], --in-place[=SUFFIX]
                 edit files in place (makes backup if SUFFIX supplied)

~ # echo 111 > 2.txt
~ # echo 13111 >> 2.txt
~ # echo 13111ddd >> 2.txt
~ # cat 2.txt
111
13111
13111ddd
~ # sed s/111/000/ 2.txt
000
13000
13000ddd
~ # sed s/111/000/g 2.txt
000
13000
13000ddd

~ # sed s/111/000/g -i 2.txt
~ # cat 2.txt
000
13000
13000ddd

~ # sed s/000/111/g -id 2.txt
~ # ll
-rw------- 1 root    root         19 Jan  8 21:10 2.txt
-rw------- 1 root    root         19 Jan  8 21:09 2.txtd
~ # cat 2.txtd
000
13000
13000ddd
~ # cat 2.txt
111
13111
13111ddd
vieyahn2017 commented 3 months ago

我自己实现的带-i的版本

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import argparse
import re

### usage:
# python sed.py -e "s/5月 [0-9][0-9]/DATE/g" 123.txt
# python sed.py -e "s/5月 [0-9][0-9]/DATE/" 123.txt
# python sed.py -e "s/admin/moon/g" 123.txt
# python sed.py -e "s/admin/moon/" 123.txt
# python sed.py -e "s/admin/moon/g" -i 123.txt

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--expr", help="expression")
    parser.add_argument("-i", "--inplace", action="store_true", default=False, help="edit files in place")
    parser.add_argument("filename", type=str)
    return parser.parse_args()

def write_file(filename, contents):
    if not contents:
        return
    with open(filename, 'w+', encoding='utf-8') as f:
        f.writelines(contents)

def match_file(old_expr, new_expr, file, count):
    inplace = args.inplace
    contents = []
    with open(file, 'r', encoding='utf-8') as f:
        for line in f.readlines():
            result = re.sub(old_expr, new_expr, line, count=count)
            if inplace:
                contents.append(result)
            else:
                print(result, end='')
    if inplace:
        write_file(args.filename, contents)

def sed_func(args):
    if args.expr.split('/')[0] == 's' and args.expr.split('/')[-1] == 'g':
        match_file(args.expr.split('/')[1], args.expr.split('/')[2], args.filename, count=0)
    elif args.expr.split('/')[0] == 's' and args.expr.split('/')[-1] != 'g':
        match_file(args.expr.split('/')[1], args.expr.split('/')[2], args.filename, count=1)

if __name__ == "__main__":
    args = parse_args()
    sed_func(args)
vieyahn2017 commented 3 months ago

python sed.py -e "s/^CERT_EXPIRE_DAYS=.*/CERT_EXPIRE_DAYS=3650/" -i 123.txt

vieyahn2017 commented 3 months ago

最新,调整match_file的参数顺序

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import argparse
import re

### usage:
# python sed.py -e "s/5月 [0-9][0-9]/DATE/g" 123.txt
# python sed.py -e "s/5月 [0-9][0-9]/DATE/" 123.txt
# python sed.py -e "s/admin/moon/g" 123.txt
# python sed.py -e "s/admin/moon/" 123.txt
# python sed.py -e "s/admin/moon/g" -i 123.txt

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--expr", help="expression")
    parser.add_argument("-i", "--inplace", action="store_true", default=False, help="edit files in place")
    parser.add_argument("filename", type=str)
    return parser.parse_args()

def write_file(filename, contents):
    if not contents:
        return
    with open(filename, 'w+', encoding='utf-8') as f:
        f.writelines(contents)

def match_file(file, old_expr, new_expr, count):
    # print((file, old_expr, new_expr, count))
    inplace = args.inplace
    contents = []
    with open(file, 'r', encoding='utf-8') as f:
        for line in f.readlines():
            result = re.sub(old_expr, new_expr, line, count=count)
            if inplace:
                contents.append(result)
            else:
                print(result, end='')
    if inplace:
        write_file(file, contents)

def sed_func(args):
    if args.expr.split('/')[0] == 's' and args.expr.split('/')[-1] == 'g':
        match_file(args.filename, args.expr.split('/')[1], args.expr.split('/')[2], count=0)
    elif args.expr.split('/')[0] == 's' and args.expr.split('/')[-1] != 'g':
        match_file(args.filename, args.expr.split('/')[1], args.expr.split('/')[2], count=1)

def sed_replace(file, old_expr, new_expr, count):
    """ match_file 的去掉inplace 参数版"""
    contents = []
    with open(file, 'r', encoding='utf-8') as f:
        for line in f.readlines():
            result = re.sub(old_expr, new_expr, line, count=count)
            contents.append(result)
    write_file(file, contents)

if __name__ == "__main__":
    args = parse_args()
    sed_func(args)