编辑
2025-03-03
工作知识
0
请注意,本文编写于 95 天前,最后修改于 95 天前,其中某些信息可能已经过时。

目录

一:grep
1.1 查找不以#开头的文本内容,并去掉空格的行
1.2 查找指定匹配字符(忽略大小写)前后5行的内容
二:cut
2.1 通过ifconfig找到所有的网卡设备名
2.2 只看内核的时间戳
三:sed
3.1 替换
3.2 插入
3.2 删除
3.3 子串匹配
四:sort
4.1 对任意文件按照行数反序
4.2 以=为分隔符对文本的第一个域的第2个字符排序,并去掉重复的行
五:uniq
5.1 找到文本中重复的行,忽略大小写,并打印重复次数
5.2 找到文本中所有不重复的行
六:awk
6.1 BEGIN和END宏
6.2 if语句
6.3 for语句
6.4 while语句
6.5 分隔符
七:总结

在使用shell环境的时候,难免会遇到对文本进行操作的情况,shell提供了一些功能强大的文本操作命令,这里做了简单汇总,有助于了解和学习这些工具,提高工作中处理文本的效率

一:grep

grep是经常使用的文本查找工具,下面列举grep常用的一些命令。当然,也有比grep更好的工具ripgrep。这个可以后续探索

1.1 查找不以#开头的文本内容,并去掉空格的行

grep -vE "^#|^$" /etc/ssh/sshd_config

-v是选中不匹配的行,-E是明确使用正则 ^$ 是没有数据的行 ^#是以#开头的行

1.2 查找指定匹配字符(忽略大小写)前后5行的内容

dmesg | grep -i cfg80211 -A 5 dmesg | grep -i cfg80211 -B 5 dmesg | grep -i cfg80211 -C 5

A after 之后的5行, B before 之前的5行, C 是A+B的合计,前后5行

-i 忽略大小写

二:cut

cut是一个字符截取命令,其命令在处理一些字符串上,可以方便的对一些字符串直接截取。如果文本内容格式比较规律的话,也可以用来筛选指定分隔符下的内容

2.1 通过ifconfig找到所有的网卡设备名

ifconfig | grep -vE "^ |^$" | cut -d ' ' -f 1 | cut -d ":" -f 1

-d 是指定分隔符, -f 是指定某个域。

-d ' ' -f 1 是以单个空格为分隔符找到第一个域

cut -d ":" -f 1 是以冒号为分隔符找到第一个域

2.2 只看内核的时间戳

dmesg | cut -b -15

三:sed

sed是重要的字符替换工具,也就流编辑器,可以方便的直接替换一些文本内容,从而不用打开文本去处理,这使得在shell内对文本替换来说十分方便

-e :添加一个命令,多个sed命令可以用这个 -i :直接修改文件内容 -n :取消自动打印,只打印模式匹配的行 -E :支持扩展表达式;

3.1 替换

cat filename | sed -e“s/text/replace/g”-e“s/text/replace/g”

-e 允许运行多个命令,s///g是替换的语法, s指的搜索,g指的全局。也就是搜索全局,然后统一替换

3.2 插入

cat filename | sed -e "4a help"

在文本第4行后添加help作为新的一行

cat filename | sed -e "4i help"

在文本第4行前添加help作为新的一行

3.2 删除

cat filename | sed -e "/^$/d"

删除空格行

cat filename | sed "s/[a-z]\|[A-Z]/[&]/g"

对文本中的所有字符加上[] 。&指的是上一次搜索到的值。 | 是或,意思可以多条规则匹配

3.3 子串匹配

echo a b | sed -E -e "s/([a-z]) ([a-z])/\2 \1/"

()可以声明这是一个字串,()声明的字串,可以通过\1 \2等通配来引用。

-E 代表使用正则,如果不加-E 则使用()的时候需要转换成 () 那么匹配一个a-z的字符需要这样表示 ([a-z])

那么不加-E 的效果如下

echo a b c | sed -e "s/\([a-z]\) \([a-z]\) \(c\)/\3 \2 \1/"

四:sort

sort是重要的字符和数字排序工具,可以直接对文本进行升序和降序操作

4.1 对任意文件按照行数反序

grep -n '.' /etc/os-release | sort -t ':' -k1 -nru

-t 指定分隔符

-k 指定分隔符划分的域

-n 指定排序方式为数字(默认为字符)

-r 指定反序

4.2 以=为分隔符对文本的第一个域的第2个字符排序,并去掉重复的行

cat /etc/os-release | sort -t '=' -k 1.2 -u

-u 去掉重复的排序行

五:uniq

uniq是找重复的工具,可以快速的识别出文本中完全重复的行,并记录次数

5.1 找到文本中重复的行,忽略大小写,并打印重复次数

cat Readme.md | uniq -dci

5.2 找到文本中所有不重复的行

cat Readme.md | uniq -u

-d 是找到完全重复的行

-c 是统计重复次数

-i 是忽略大小写

-u 是打印不重复的行

六:awk

awk模式是模式扫描及处理语言,也就是说文本处理规则太多了,我定义一个语言,你们想怎么匹配就怎么匹配

NF 一条记录的字段的数目 NR 行号,当前处理的文本行的行号 FS 定义间隔符 OFS 定义输出字段分隔符,默认空格  RS 输入记录分隔符,默认换行

awk默认格式为

awk '{pattern + action}' {filenames}

这里'{}'里面就是代码域,用于编写awk代码的地方。

最简单的打印可以如下

echo | awk '{print "Hello World"}'

直接打印hello world

echo Hello World | awk '{print $1" "$2}'

打印传过来的参数

6.1 BEGIN和END宏

cat /etc/passwd | awk 'BEGIN{count=0;print "begin is:" count} {count=count+1;print count} END{print "end is:"count}'

这里统计了passwd的文件行数

awk不仅默认{}里面填写代码,也可以在BEGIN和END宏里面填写代码,BEGIN填写的代码,在{}前运行,END填写的代码在{}后运行

ll |awk 'BEGIN {byte=0;print "统计当前目录占用字节数"} {byte=byte+$5;} END{print "当前目录字节数为:",byte}'

这里统计了当前目录的字节数,不包括下级目录

6.2 if语句

cat /etc/passwd | awk '{if(NR>=10 && NR<=20) print $1}'

这里取passwd文件的第10行到20行内容

'{}'的if语句可以和C语言一样,print可以和python语言一样。

6.3 for语句

cat /etc/passwd | awk -F '' 'BEGIN{count=0} {for(i=1; i<=NF; i++) count++} END{print count}'

这里对每个字符做计数,最后打印存在的字符总数。

6.4 while语句

echo abcdefg | awk -F '' '{i=1; while(i<=length($0)) {print $i;i++}}'

这里对一行abcdefg转换成一个字母多行

6.5 分隔符

echo "1 2,3:4" | awk -F [" ",:] '{print $1$2$3$4}'

以空格,逗号,冒号作为分隔符打印第1,2,3,4个匹配的内容

echo "1 2,3:4" | awk BEGIN{'FS="[ ,:]"} {print $1$2$3$4}'

FS宏也可以代替-F参数,需要注意的是,FS参数需要在后面加上"" 双引号

七:总结

这里介绍了grep sort uniq awk sed cut一共六个命令,每个命令都可以搭配起来使用。这里简要介绍一下在哪些情况下可以用哪些命令

1.搜索一些匹配单词的时候,可以用grep,例如 grep -nr text filename 2.面临排序问题的时候,可以用sort, 例如 sort -r 3.去重复行的时候,可以用uniq, 例如 uniq -u 4.批量替换的时候,可以用sed,例如 sed -i “s/text/replace/g” 5.对特定格式字符串进行截取的时候,可以用cut ,例如 cut b 1-3 6.在对一些列的域做划分的时候,可以用awk , 例如 awk -F ‘:’ '{print $1}' 7.对文本进行高级编辑操作的时候,awk都能完成.