首页 / 知识
如何把awk脚本移植到Python
2023-11-12 13:37:00
将一个awk脚本移植到Python主要在于代码风格而不是转译。
脚本是解决问题的有效方法,而awk是编写脚本的出色语言。它特别擅长于简单的文本处理,它可以带你完成配置文件的某些复杂重写或目录中文件名的重新格式化。
何时从awk转向Python
但是在某些方面,awk的限制开始显现出来。它没有将文件分解为模块的真正概念,它缺乏质量错误报告,并且缺少了现在被认为是编程语言工作原理的其他内容。当编程语言的这些丰富功能有助于维护关键脚本时,移植将是一个不错的选择。
我最喜欢的完美移植awk的现代编程语言是Python。
在将awk脚本移植到Python之前,通常值得考虑一下其原始使用场景。例如,由于awk的局限性,通常从Bash脚本调用awk代码,其中包括一些对sed、sort之类的其它命令行常见工具的调用。最好将所有内容转换为一个一致的Python程序。有时,脚本会做出过于宽泛的假设,例如,即使实际上只运行一个文件,该代码也可能允许任意数量的文件。
在仔细考虑了上下文并确定了要用Python替代的东西之后,该编写代码了。
标准awk到Python功能
以下Python功能是有用的,需要记住:
withopen(some_file_name)asfpin:
forlineinfpin:
pass#dosomethingwithline
此代码将逐行循环遍历文件并处理这些行。
如果要访问行号(相当于awk的NR),则可以使用以下代码:
withopen(some_file_name)asfpin:
fornr,lineinenumerate(fpin):
pass#dosomethingwithline
在Python中实现多文件的awk式行为
如果你需要能够遍历任意数量的文件同时保持行数的持续计数(类似awk的FNR),则此循环可以做到这一点:
defawk_like_lines(list_of_file_names):
def_all_lines():
forfilenameinlist_of_file_names:
withopen(filename)asfpin:
yieldfromfpin
yieldfromenumerate(_all_lines())
此语法使用Python的生成器和yieldfrom来构建迭代器,该迭代器将遍历所有行并保持一个持久计数。
如果你需要同时使用FNR和NR,这是一个更复杂的循环:
defawk_like_lines(list_of_file_names):
def_all_lines():
forfilenameinlist_of_file_names:
withopen(filename)asfpin:
yieldfromenumerate(fpin)
fornr,(fnr,line)in_all_lines:
yieldnr,fnr,line
更复杂的FNR、NR和行数的awk行为
如果FNR、NR和行数这三个你全都需要,仍然会有一些问题。如果确实如此,则使用三元组(其中两个项目是数字)会导致混淆。命名参数可使该代码更易于阅读,因此最好使用dataclass:
importdataclass
@dataclass.dataclass(frozen=True)
classAwkLikeLine:
content:str
fnr:int
nr:int
defawk_like_lines(list_of_file_names):
def_all_lines():
forfilenameinlist_of_file_names:
withopen(filename)asfpin:
yieldfromenumerate(fpin)
fornr,(fnr,line)in_all_lines:
yieldAwkLikeLine(nr=nr,fnr=fnr,line=line)
你可能想知道,为什么不一直用这种方法呢?使用其它方式的的原因是总用这种方法太复杂了。如果你的目标是把一个通用库更容易地从awk移植到Python,请考虑这样做。但是编写一个可以使你确切地了解特定情况所需的循环的方法通常更容易实现,也更容易理解(因而易于维护)。
理解awk字段
一旦有了与一行相对应的字符串,如果要转换awk程序,则通常需要将其分解为字段。Python有几种方法可以做到这一点。这将把行按任意数量的连续空格拆分,返回一个字符串列表:
line.split()
如果需要另一个字段分隔符,比如以:分隔行,则需要rstrip方法来删除最后一个换行符:
line.rstrip("\n").split(":")
完成以下操作后,列表parts将存有分解的字符串:
parts=line.rstrip("\n").split(":")
这种拆分非常适合用来处理参数,但是我们处于偏差一个的错误场景中。现在parts[0]将对应于awk的$1,parts[1]将对应于awk的$2,依此类推。之所以偏差一个,是因为awk计数“字段”从1开始,而Python从0开始计数。在awk中,$0是整个行——等同于line.rstrip("\n"),而awk的NF(字段数)更容易以len(parts)的形式得到。
移植awk字段到Python
例如,让我们将这个单行代码“如何使用awk从文件中删除重复行”转换为Python。
awk中的原始代码是:
awk'!visited[$0]++'your_file>deduplicated_file
“真实的”Python转换将是:
importcollections
importsys
visited=collections.defaultdict(int)
forlineinopen("your_file"):
did_visit=visited[line]
visited[line]+=1
ifnotdid_visit:
sys.stdout.write(line)
但是,Python比awk具有更多的数据结构。与其计数访问次数(除了知道是否看到一行,我们不使用它),为什么不记录访问的行呢?
importsys
visited=set()
forlineinopen("your_file"):
iflineinvisited:
continue
visited.add(line)
sys.stdout.write(line)
编写Python化的awk代码
Python社区提倡编写Python化的代码,这意味着它要遵循公认的代码风格。更加Python化的方法将区分唯一性和输入/输出的关注点。此更改将使对代码进行单元测试更加容易:
defunique_generator(things):
visited=set()
forthinginthings:
ifthinginvisited:
continue
visited.add(things)
yieldthing
importsys
forlineinunique_generator(open("your_file")):
sys.stdout.write(line)
将所有逻辑置于输入/输出代码之外,可以更好地分离问题,并提高代码的可用性和可测试性。
结论:Python可能是一个不错的选择
将awk脚本移植到Python时,通常是在考虑适当的Python代码风格时重新实现核心需求,而不是按条件/操作进行笨拙的音译。考虑原始上下文并产生高质量的Python解决方案。虽然有时候使用awk的Bash单行代码可以完成这项工作,但Python编码是通往更易于维护的代码的途径。
以上内容为大家介绍了如何把awk脚本移植到Python,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注我们http://www.mobiletrain.org/
最新内容
相关内容
For循环如何在Python中工作
For循环如何在Python中工作,工作,项目,代码,培训,流程,示例,序列,语句,语法,实际,Python的for循环通过遍历数组的序列来工作。从本质上讲,它在为什么开发人员喜欢在机器学习和人
为什么开发人员喜欢在机器学习和人工智能项目中使用Python?,代码,项目,数据,人工智能,平台,异常,增长,灵活,时间,工具,1.Python是灵活的Pytho为何你的Python代码应是扁平与稀疏
为何你的Python代码应是扁平与稀疏的,代码,培训,信息,观察,设计,工具,嵌套,闻闻,程序员,沉思,Python之禅之所以得名,正是由于它那简明扼要的规用Python开发一个简单的猜数字游戏
用Python开发一个简单的猜数字游戏,数字,代码,培训,官网,设备,程序,玩家,注释,内容,游戏,本文介绍如何使用Python制作一个简单的猜数字游戏。如何提速优化python代码?
如何提速优化python代码?,代码,时间,数据,新增,写法,包装,情况,下来,面临,工作,Python是一种脚本语言,相比C/C++这样的编译语言,在效率和性能方学习Python可以做这些工作
学习Python可以做这些工作,网络,数据,工作,网站,技术,培训,行业,发展,人工智能,分析,Python语言非常受欢迎,随着互联网的快速发展,很多不是计算python经典最短代码实现排序的功能
python经典最短代码实现排序的功能,代码,位置,数据,分析,时间,序列,元素,培训,下来,算法,冒泡排序:算法思想:1.比较相邻的元素,如果第一个比第二Python编程可以干这些工作
Python编程可以干这些工作,工作,分析,网络,数据,数字,销售,行政,人工智能,网站,培训,学Python编程能做什么工作?随着人工智能发展,学习pythonPylint让Python代码保持一致
Pylint让Python代码保持一致,代码,项目,数字,位置,地方,设计,工具,培训,一致,准则,当你想要争论代码复杂性时,Pylint是你的朋友。Pylint是更高Python标准库之collections模块
Python标准库之collections模块,名字,标准,信息,电话号码,培训,工厂,位置,简介,异常,对象,collections模块简介collections是Python标准库里用于业余项目的优秀 Python 库
用于业余项目的优秀 Python 库,数据,工具,项目,信息,培训,系统,地图,下来,工作,管理,1.在数据库中即时保存数据:Dataset当我们想要在不知道最Python爬虫学到什么程度可以找工作
Python爬虫学到什么程度可以找工作,技术,项目,网站,网上,下来,系统,公司,数据,占比,工具,有同学在群里和大家讨论,问的最多的问题就是,python爬