当前位置: 首页 > 科技观察

编程技巧之Linux文本处理命令

时间:2023-03-21 14:58:28 科技观察

本文转载自微信公众号《程序员李小兵》,作者李小兵。转载本文请联系程序员李小兵公众号。合格的程序员善于使用工具。正所谓君子不异,善于事。合理使用Linux命令行工具可以提高我们的工作效率。本篇文章是?的续篇。在上一篇文章的基础上,我将介绍几个好用的Linux命令行工具和使用场景。多说一句,工具可以提供效率,但是有一定的学习曲线和学习成本。很多同学在想临时使用的时候,可能会陷入用不上的尴尬境地。网上搜索学习时间会长一些,还不如用笨办法对付。这是许多学生不使用这些工具的原因之一。更难的是在思维上要改变原有的工作习惯。一个文件中有20多行数据生成SQL。手动处理好像需要1、2分钟;非常快。但是当行数变大或者复杂度增加时,这些方法的缺点就会显现出来,迫使我们使用正确的方法。那么,为什么不从一开始就使用更快并且可以处理更复杂场景的东西呢?本文主要以两个场景作为介绍,分别介绍join、sort、uniq命令和sed编辑器。合并两个文件中的关联行让我们简单谈谈这个场景。有两个行格式固定的文件,代表数据库中的一行数据。一个文件是用户相关的数据,有三列:user_id、username、gender。另一个文件是订单相关数据,有四行order_id、price、user_id、time。现在,这两个文件需要根据user_id逐行合并,即将user_id相同的行合并成一个新行,如下图所示。上面两个文件的内容如下://order.txtuser_id是第三列o11u12011-9o22u22011-10o33u32011-10o44u12011-12//user.txtuser_id是第一列u1tommaleu2jackmaleu3nacyfemale我们要用join并找出具体的命令格式忘记了。这时候你要么上网搜索,要么通过man问man,就可以了解到join的功能说明和参数介绍。一般来说,看DESCRIPTION那一栏就可以了。从上面的man文档中可以看出,join命令使用相等连接操作来合并特定的文件并输出到标准输出流。joinfiled是合并文件时用来比较的列,默认是两个文件的第一列。您可以使用-1和-2分别指定第一个文件和第二个文件中要比较的列。$join-13-21order.txtuser.txt#指定order.txt第三列和user.txt第一列对比joinu1o112011-9tom男u2o222011-10jack男u3o332011-10nacy女你会发现输出少了一个行,order.txt明明是四行,为什么?我们再看看man文件,找出端倪。合并后的两个文件的行必须先按照比较列排序,否则可能会丢失一些行。user.txt已经按第一列排序,所以我们只需要使用sort命令按第三列对order.txt进行排序。sort命令默认按照ASCII码顺序对文本文件的第一列进行排序,并将结果输出到标准输出。-k参数可以指定按哪一列进行排序。$sort-k3order.txt#使用-n按数字排序,使用-ro44u12011-12o11u12011-9o22u22011-10o33u32011-10倒序。我们结合上面两个命令,现在将排序后的结果存入sorted_order.txt,然后再次join得到最终的结果。$sort-k3order.txt>sorted_order.txt$join-13-21sorted_order.txtuser.txttu1o442011-12tommaleu1o112011-9tommaleu2o222011-10jackmaleu3o332011-10nacy另外上面命令默认的列分隔符是\t和空格,可以使用-t参数指定字符作为分隔符。通过以上命令的组合,我们完成了将两个文件按照同一列合并的操作,这也体现了Linux的KISS思想,每个工具只做一件小事。还是基于上面的场景,突然需要在order.txt中统计每个用户购买的订单数,然后根据订单数从大到小排序。如何处理?我们可以把sort和uniq这两个工具结合起来。uniq命令一般用于检查和删除文件中重复的行,我们可以用它来统计一个用户在order.txt中出现的次数。$sort-k3order.txt|uniq-f3-c#-f表示根据第三列统计1o44u12011-121o11u12011-92o22u22011-10删除Markdown文件中的超链接我在编辑文章时遇到的另一个场景是markdown格式超链接很多在文档中,也就是[描述](链接)格式,希望去掉所有的超链接,也就是去掉方括号,括号和括号里的内容。因为文档中还有很多代码,包括很多括号语句,所以在替换之前需要正确格式化超链接。在这里,我们可以使用sed命令。sed的全称是streameditor流编辑器,可以用程序的方式编辑文本。想全面了解它的朋友可以阅读《SED 简明教程》或《sed 手册》。这里我们只介绍最基本的功能,让您看到使用它的可能性。使用sed时,一般需要了解正则表达式,推荐《正则表达式30分钟入门教程》。使用sed最简单的方法是替换文本。比如我们要把上面order.txt中的u全部替换成user,可以使用如下命令。$sed's/u/user/g'order.txt#u为替换词user为替换词o11user12011-9o22user22011-10o33user32011-10o44user12011-12sed也可以轻松实现sublime或vscode常用的多行光标编辑功能。例如,在order.txt的每一行之前添加文本。$sed's/^/#/g'order.txt#^表示正则表达式中的行首,所以表示在行首添加#字符#o11u12011-9#o22u22011-10#o33u32011-10#o44u12011-12接下来我们直接看如何将超链接格式转换为纯文本。$echo"[链接](http://http://remcarpediem.net/)"|sed-E"s/\[(.*)]\(.*\)/\1/g"linkfirst,识别[description](链接)格式的正则表达式为\[.*\]\(.*\),其中\[和\(分别代表匹配文本的[和(符号。.代表任意单个字符,*代表一个字符出现0次或多次,两者结合。*表示任何字符出现0次或多次。总结一下,上面的正则表达式的意思就是先出现一个[,然后任意一个字符出现0次或多次,再出现一个],再出现一个(,任意一个字符出现0次或多次,一个字符出现在其次,我们要用[Description]中的描述文字替换整个超链接文字,所以需要先识别方括号中的内容,然后单独用()括起来表示一个子表达式,即\[(.*)\]\(.*\)。最后在sed的s///g模式中,s表示替换模式,g表示匹配从头到尾的所有字符每一行的。如果加g,则一行中有多个链接可以匹配。如果不加,则只能匹配第一个。\1代表第一个子表达式,也就是square中的描述括号。