天天看点

来聊一聊不low的Linux命令——find、grep、awk、sed

前几天面试,被一位面试官嫌弃了“你的Linux命令有点low”。说心里话,还是挺感激的,因为很少有面试官会指出我的简历上出现的问题。所以呢,今天就来聊一聊不low的Linux命令——搜索文件的find命令、搜索文件内容的grep命令、对文件内容进行统计的awk命令、批量替换文件内容的sed命令。

前几天面试,被一位面试官嫌弃了“你的Linux命令有点low”。被嫌弃也挺正常的,因为我的简历写的我自己都有点看不下去:了解Linux常用命令,如<code>ls</code>,<code>tail -f</code>等命令,基本满足日常的开发。面试官人很好,整个面试进行地也很愉快。说心里话,还是挺感激的,因为很少有面试官会指出我的简历上出现的问题。所以呢,今天就来聊一聊不low的Linux命令——搜索文件的find命令、搜索文件内容的grep命令、对文件内容进行统计的awk命令、批量替换文件内容的sed命令。

find命令是一个用于搜索文件的命令。find命令的基本语法:<code>find path [option] params</code>

path为搜索文件的路径,可以是相对路径,也可以是绝对路径,还可以指定多个路径,如:<code>find /var /home</code>。

主要选项(option)如下:

选项

含义

-depth

在查看目录本身之前先搜索目录的内容

-follow

跟随符号链接

-maxdepths N

最多搜索N层目录

-mount

不搜索其他文件系统中的目录

主要参数(param)如下:

参数

-atime N

文件在N天之前被最后访问过

-mtime N

文件在N天之前被最后修改过

-name pattern

文件名需要匹配pattern

-newer otherfile

文件比其他文件要新

-type c

文件类型为c,最常见的是d(目录)和f(普通文件)

-user username

文件的拥有者是username

-size +1M

文件大小。例子为查找文件大小大于1M的。

-perm 644

文件权限。例子为查找文件权限为644的。

精确查找文件:<code>find ~ -name "spur.java"</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

模糊查找:<code>find ~ -name "spur*"</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

模糊查找可以找到spur开头的文件和目录,那如果要单独查找目录或者单独查找文件怎么办呢?

其实有个<code>-type</code>可以用来筛选目录和文件,查找文件在上面的命令后面添加<code>-type f</code>,查找目录加<code>-type d</code>。

忽略文件名大小写进行查找文件:<code>find ~ iname "spurt*"</code>

查找文件并恢复文件权限:<code>find -type f -exec chmod -R 644 {} \;</code>

删除30天之前的日志文件:<code>find -type f -name "*.log" -mtime +30 -exec rm -rf {} \;</code>

grep (缩写来自Globally search a Regular Expression and Print)是一种强大的文本搜索工具,它能使用特定模式匹配(包括正则表达式)搜索文本,并默认输出匹配行,基本语法为<code>grep [options] pattern [file]</code>

如果没有提供文件名,则grep命令将会搜索标准输入。

主要选项(option)如下表:

-c

输出匹配行的数目

-h

取消每个输出行的普通前缀

-i

忽略大小写

-l

查找多个文件,只列出包含匹配行的文件名

-v

反向查找

-n

顺便输出行号

在文件中搜索字符串,然后输出匹配的行。例如匹配文件spur.txt中的字符串for,并输出整行,要求带行号:<code>grep -n for spur.txt</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

计算匹配的行的数目:<code>grep -c for spur.txt</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

管道操作符“|”可将指令连接起来,前一个指令的输出作为后一个指令的输入。注意:只有前一个命令正确输出的时候,才会处理后一个命令。例如:<code>find ~ | grep for</code>

来聊一聊不low的Linux命令——find、grep、awk、sed
管道和重定向的区别:管道是一个连接一个进行计算;重定向是将一个文件的内容定向到另一个文件;这二者经常结合使用。

匹配ip地址:<code>egrep --color "([0-9]{1,3}\.){3}[0-9]{1,3}$" test.txt</code>

AWK是Unix系统下一个非常强大的文本处理工具。AWK其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 本身也可以作为一门计算机脚本语言。它允许创建简短的程序,这些程序可以读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表等其他的功能。

awk知识要点

语法:<code>awk [options] 'cmd' file</code>

一次读取一行文本,按输入分隔符进行切片,切成多个组成部分(一行为一个record,一列为一个field)

将切片直接保存在内建的变量中,$1,$2...($0表示行的全部)

支持对单个切片的判断,支持循环判断,默认分隔符为空格

这里有个spur.txt的文件,文件内容如下:

来聊一聊不low的Linux命令——find、grep、awk、sed

使用awk命令查看全部文件内容:<code>awk '{print}' spur.txt</code>

print是awk的内置函数,用于打印出变量的值。

来聊一聊不low的Linux命令——find、grep、awk、sed

打印某一列或者某几列:$1为第1列,$2为第2列,...($0表示全部)

以打印第1列和第4列为例:<code>awk '{print $1,$4}' spur.txt</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

分隔符的使用。

awk认为“,”为系统默认分隔符,“ ”为直接连接起来。

来聊一聊不low的Linux命令——find、grep、awk、sed

例如第2个例子中<code>awk '{print $1,$4}' spur.txt</code>,使用的是默认分隔符,结果两列之间有空格隔开的。

本例子使用<code>awk '{print $1 $4}' spur.txt</code>,使用的是直接相连,结果两列之间没有空格隔开。

当然,也可以自定义分隔符。如果希望用“-”分割,可以这么写:<code>awk '{print $1 "-" $4}' spur.txt</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

内置变量NR和NF的使用。

Awk定义一行为一个record,一列为一个field。NR为行数(number of record),NF为列数(number of field)。

例如查找打印最后一列为2794的记录并打印:<code>awk '$NF==2794{print $0}' spur.txt</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

BEGIN语句块和END语句块。

BEGIN用于awk 开始处理输入文件中的文本之前执行初始化代码。

END用于执行最终计算或打印应该出现在输出流结尾的摘要信息。

继续以分隔符举例,我们可以使用BEGIN语句块来定义全局变量,FS为输入分隔符,OFS为输出分隔符。

提示:如果awk命令后面不加文件名,awk则认为下一行输入的内容为需要处理的内容。

设置“,”为输入分隔符,“\t”为输出分隔符:

来聊一聊不low的Linux命令——find、grep、awk、sed

正则表达式(Regular Expression)的使用。

正则表达式估计大家都比较了解,就不多唠叨了,下面列出几个常用的:

字符

描述

.

匹配任意一个字符

^

匹配开头。/^abc/匹配以abc开头字符串

$

匹配结尾。/abc$/匹配以abc结尾的字符串

[abc]

字符集合。匹配所包含的任意一个字符。

[^a-z]

^放在方括号里面表示非。<code>[^a-z]</code>匹配不是a-z的字符串

*

匹配前面的子表达式零次或多次。

+

匹配前面的子表达式一次或多次。

?

匹配前面的子表达式零次或一次。

{n}

匹配n次。<code>/ab{3}c/</code>匹配b出现3次。

{n,m}

匹配n-m次。<code>ab{3,10}c</code>匹配b可以出现3次至10次。

{n,}

至少匹配n次。<code>/ab{3,}c/</code>匹配b出现3次及3次以上。

()

()看成一个整体。<code>/(ab)+c/</code>:ab作为一个整体,至少出现一次。

例如需要匹配出马刺队所有的后卫球员,也就是正则匹配spur.txt中包含<code>guard</code>的记录:<code>awk '/guard/{print $0}' spur.txt</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

匹配第3列以“te”结尾,打印所有的列:<code>awk '$3 ~ /(te)$/{print $0}' spur.txt</code>

来聊一聊不low的Linux命令——find、grep、awk、sed

注意:“~”表示模式开始。“//” 中是模式。

这是一道我面试某视频娱乐公司的面试题,像这种难度的小问题还希望大家多重视。

更多的操作可以参考:Awk官方文档

Sed的全名为Stream Editor,流编辑器,适合用于对文本的行内容进行处理。基本语法为:<code>sed [option] 'sed command' filename</code>

常用的选项:

使用安静模式

-e

直接在指令列模式上进行 sed 的动作编辑

-f

直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作

-r

在脚本中使用扩展正则表达式

直接修改读取的档案内容,而不是将修改结果输出到终端上

常用的命令:

命令

a

新增行

c

取代行

d

删除行,d 后面通常不加任何字符

i

插入行

p

打印

s

替代

删除指定的行(删除1-3行为例):<code>sed '1,3d' replace.txt</code>

新增一行:<code>sed '1a hello world' replace.txt</code>

替换某行:<code>sed '1c hello world' replace.txt</code>

把“Str”开头的行替换为“String”,仅输出到终端显示:<code>sed 's/^Str/String/' replace.txt</code>

字符串替换,把<code>replace.txt</code>中全部的“Jack”替换为“me”,要求在文档中修改:<code>sed -i 's/Jack/me/g' replace.txt</code>

替换末尾的“.”为“;”:<code>sed -i 's/\.$/\;/' replace.java</code>

本文介绍了find命令、grep命令、awk命令、sed命令的基本使用方法,希望对大家有帮助。

由于博主也是在攀登的路上,文中可能存在不当之处,欢迎各位多指教! 如果文章对您有用,那么请点个”推荐“,以资鼓励!

继续阅读