当涉及文件解析或者数据预处理时,你首先想到的编程语言是什么?
Python、R、Java等编程语言会出现在脑海里。
当然,这些高级编程语言功能强大,通常我们只需要几十行代码就可以实现我们的目标。
但是,Linux Shell这么强大的工具似乎被很多开发者遗忘了。
因为它的语法相对落后,而且线上教程不那么直观,社区也不是特别完善。所以,很多有开发者会首先想到利用Linux Shell进行数据处理。
在本文中,我将带你了解Shell命令在某些情况下到底有多么强大,更重要的是,你可以轻松学习,并且能够在日常的小需求中使用它。
本文主要围绕awk
进行讲解,或许很多同学用过或者了解过awk
。因此,在这里就简单的概括一下。
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
分隔符
分隔符是在数据处理过程中经常会接触到的一类问题,csv
、日志文件,会都会涉及各种各样的分隔符。
在处理数据过程中就需要对这些分隔符进行分割、替换,以便于数据的处理和分析。
举个例子,假如我有一份csv
数据,是以逗号作为分隔符,
index,col1,col2,col3 1,5,6,7 2,a,b,c 3,uu,vv,ww
现在我需要把逗号修改为tab
,可以用下方命令:
awk '{$1=$1}1' FS="," OFS="\t" file4.csv > file4.txt
下面看一下输出结果,
index col1 col2 col3 1 5 6 7 2 a b c 3 uu vv ww
如果使用编程语言,此时你需要打开IDE,新建项目,编写代码。如果使用Linux Shell,只需要打开终端命令行即可。
现在让我们深入研究语法本身,解释一下上述命令的作用:
{$1=$1}1
:重置缓冲区FS=","
:原始分隔符OFS="\t"
:新的分隔符
然后,你只需要指定输入文件和输出文件即可!
相对于编程语言,Shell命令最酷的地方是,它通常预装在您的PC上,你无需担心设置环境,安装软件包(例如python pandas软件包)的麻烦。
转置
为了说明问题,假设你有以下文件:
item1 item2 item3 item4
为了使它们垂直显示,你只需要一行代码:
awk '{for(i=1;i<=NF;i++){print $i}}' file5.txt > file5_new.txt
输出结果:
item1 item2 item3 item4
这个awk
命令的作用是,对于每一行(在此输入文件中,我们只有一行),在列上进行遍历,从索引i = 1(第一列)开始,以索引i = NF
,NF
结束 是awk
中的特殊变量,代表每行的长度。
因此,上面的命令简单地说,对于列中的每个item
,我们将其一一打印出来,每个item
将占据整行,这使我们能够在这里实现自己的目标。
然后您可能会问,如果我有一个垂直输出,但我希望水平显示,您能撤消操作吗?当然!
cat file5_new.txt | tr '\n' ' ' | awk '{$1=$1}1' FS=" " OFS="\t" > file5_restore.txt
来看一下结果:
item1 item2 item3 item4
对这个命令的一些解释,我们首先使用cat
读取文件,然后使用tr
命令将每一行的换行符替换为空格,这就可以实现我们的目标。
awk
基本用法
通过前面的示例,已经清楚了awk
的强大之处,下面通过一个非常经典的任务,来指导你了解awk命令的基本语法。
假设你有一个如下文件:
index col2 col3 col4 i1 John 56 male i2 Mary 34 female i3 Frank 23 male i4 Chris 58 female
我想知道col3
的总和,可以在一行代码中实现吗?
这很有用,因为在现实生活中,输入文件可能有100万行,而不是示例中简单的4行。
awk 'BEGIN{FS="\t";count=0}{if(NR>1){count+=$3}}END{print count}' file6.txt #输出 171
下面,介绍一下awk
常用的标识符,这样就能够很清楚的了解上述命令的原理:
BEGIN
:在开始处理每一行之前执行MAIN
:在处理每一行过程中执行END
:在结束每一行的处理之后执行FS
:输入文件的分隔符OFS
:输出文件的分隔符NR
:行号NF
:每一行的长度
awk
逐行处理文件,但是它将在处理每一行之前可以在BEGIN
中执行某些操作,并在完成处理每一行后执行一些操作。此属性使我们能够轻松地计算均值或总和。
因此,针对上述问题,当我们初始化一个计数变量并将其值累加到最后时,我们可以打印出最终的计数或将其取平均值以获得均值。
这样一来,我们将发现仅使用awk
就可以在Linux Shell中完成许多任务。
为什么使用Linux Shell
目前,Python可以以更结构化的格式解决大多数任务的事实,为什么我们需要学习Shell命令?
答案是,Shell具有如下独特的优势:
- 在Python中,我们需要处理变量,在内存中处理了数十个变量,然后,获得了所需的输出。但是在Shell中,我们处理的对象是文件,这使得,你只需要几行代码就可以完成成千上万文件的处理。
- Shell命令允许你执行跨语言任务,或将多个Python,R甚至Matlab脚本粘合在一起作为元脚本。
- 在某些情况下,Shell命令比其他脚本语言更方便。
- Linux系统普遍存在于云计算平台,不需要经过任何额外配置
结语
开发过程中,首先应该清晰的认识到我们的目标是完成任务,而不是“炫技”。
解决一个问题可以寻找出很多不同的方法,但是如果在忙碌的工作中选取出最有效的方法,提升效率,这需要作为开发者的我们认真考虑的。
处理文件和数据过程中,使用Shell一行代码就可以实现其他语言几十行才能完成的任务,何乐而不为呢?