shell最全基础2020年入门---从熟悉grep、sed、awk开始

前言

本文是对shell以及文本三剑客grep、sed、awk进行科普,如果对shell脚步不是非常熟悉的同学,很欢迎仔细读本文。

如果对理论不敢兴趣,可以直接跳到,grep使用实例,sed使用实例,awk使用实例

本文纯原创,感谢支持

一、什么是shell

Shell是命令解释器(command interpreter),是Unix操作系统的用户接口,程序从用户接口得到输入信息,shell将用户程序及其输入翻译成操作系统内核(kernel)能够识别的指令,并且操作系统内核执行完将返回的输出通过shell再呈现给用户

在这里插入图片描述

shell脚本

指.sh结尾的脚本
1、一个shell脚本通常包含如下部分:

  • (1)、首行

第一行内容在脚本的首行左侧,表示脚本将要调用的shell解释器,内容如下:
#!/bin/bash

  • (2)、注释

注释符号# 放在需注释内容的前面,如下:

  • (3)、内容

可执行内容和shell结构

2、一个完整的shell脚本
first.sh

#!/bin/bash
# my firest shell
echo "hello world"

3、尝试运行我们第一个shell脚本

1、创建文件夹
mkdir /usr/local/myshell
2、创建文件
vi /usr/local/myshell/first.sh
3、复制我们的shell脚本
4、赋予执行文件权限
chmod +x /usr/local/myshell/first.sh
5、执行文件
/usr/local/myshell/first.sh
6、执行结果
hello world

本文不是主要讲shell脚本,如有兴趣,可以关注下一篇文章

大白话

windows是通过图形界面操作的,而linux是通过shell操作一个个命令的。

二、shell常用操作

ls 列出文件的目录

[root@k8s-master /]# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

cd 进入目录

[root@k8s-master /]# cd usr/local/myshell/
[root@k8s-master myshell]#

ps 查看正在运行软件

[root@k8s-master myshell]# ps -aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.3  0.1 125900  3716 ?        Ss   5月07   3:15 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2  0.0  0.0      0     0 ?        S    5月07   0:00 [kthreadd]
root          4  0.0  0.0      0     0 ?        S<   5月07   0:00 [kworker/0:0H]
root          6  0.0  0.0      0     0 ?        S    5月07   0:52 [ksoftirqd/0]

ps 某一个线程,如我查看docker线程

[root@k8s-master myshell]# ps -ef|grep docker
root       1035      1  2 5月07 ?       00:25:57 /usr/bin/dockerd
root       1184   1035  0 5月07 ?       00:03:02 docker-containerd --config /var/run/docker/containerd/containerd.toml

find 查看linux中某一个文件的路径
为了节省时间,最好指定某一个路径,按照名字进行查找

查找路径etc下,名字为password开头的文件
[root@k8s-master myshell]# find /etc -name password*
/etc/openldap/certs/password
/etc/pam.d/password-auth-ac
/etc/pam.d/password-auth

pwd查看当前工作目录

[root@k8s-master myshell]# pwd
/usr/local/myshell

rm 删除文件
mv 移动文件
cp 复制文件
cat 查看文件
vi 编辑文件

如果对shell基本操作有兴趣可以自己百度,下面进入正题,文本处理三剑客,grep、sed、awk

三、文本处理三剑客 — 搜索工具grep

1.什么是grep

Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。

2.格式

grep [options]

3.主要参数

 [options]主要参数:
-c:只输出匹配行的计数。
-i:不区分大小写(只适用于单字符)。
-h:查询多文件时不显示文件名。
-l:查询多文件时只输出包含匹配字符的文件名。
-n:显示匹配行及行号。
-s:不显示不存在或无匹配文本的错误信息。
-v:显示不包含匹配文本的所有行。
-w: 完全匹配

4.pattern正则表达式主要参数:

\: 忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
\<:从匹配正则表达式的行开始。
\>:到匹配正则表达式的行结束。
[ ]:单个字符,如[A]即A符合要求 。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
。:所有的单个字符。
* :有字符,长度可以为0。

5. grep使用实例

本文只介绍一种使用方法,就是如何在复杂的文本中查找出自己想要东西
(1)、直接查找进程, 发现数量实在太多

[root@k8s-master myshell]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 5月07 ?       00:03:27 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2      0  0 5月07 ?       00:00:00 [kthreadd]
root          4      2  0 5月07 ?       00:00:00 [kworker/0:0H]
root          6      2  0 5月07 ?       00:00:56 [ksoftirqd/0]
。。。

改进,采用grep过滤,把docker进程过滤出来

[root@k8s-master myshell]# ps -ef|grep docker
root       1035      1  2 5月07 ?       00:27:53 /usr/bin/dockerd
root       1184   1035  0 5月07 ?       00:03:14 docker-containerd --config /var/run/docker/containerd/containerd.toml

把java进程过滤出来,发现我没有运行java程序

[root@k8s-master myshell]# ps -ef|grep java
root      92443  66231  0 03:22 pts/0    00:00:00 grep --color=auto java

(2)、为了方便大家理解,我们创建一个文件来进行解释,请大家消化吸收一下参数的意义

cat /usr/local/myshell/greptest
大狗 花色 1岁 5.2斤
小狗 红色 0.8岁 5.3斤
花猫 白色 1.8岁 4.2斤
兔子 黑色 0.7岁 2.3斤
  1. -c:只输出匹配行的计数。
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep -c 狗
2
  1. -n:显示匹配行及行号。
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep -n 花
1:大狗 花色 1岁 5.2斤
3:花猫 白色 1.8岁 4.2斤
  1. -v:显示不包含匹配文本的所有行。
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep -nv 花
2:小狗 红色 0.8岁 5.3斤
4:兔子 黑色 0.7岁 2.3斤

(3)、正则表达式

  1. ^:匹配正则表达式的开始行。
    以大开头的
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep ^大
大狗 花色 1岁 5.2斤

在这里插入图片描述

  1. $: 匹配正则表达式的结束行。
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep 3斤$
小狗 红色 0.8岁 5.3斤
兔子 黑色 0.7岁 2.3斤
  1. [ ]:单个字符,如[A]即A符合要求 。
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep [花岁]
大狗 花色 1岁 5.2斤
小狗 红色 0.8岁 5.3斤
花猫 白色 1.8岁 4.2斤
兔子 黑色 0.7岁 2.3斤

在这里插入图片描述

  1. [ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep [4-6]
大狗 花色 1岁 5.2斤
小狗 红色 0.8岁 5.3斤
花猫 白色 1.8岁 4.2斤
  1. . :所有的个字符。
-w: 完全匹配
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep -w 1.
大狗 花色 1岁 5.2斤
  1. *:多个字符,长度大于1个
[root@k8s-master myshell]# cat /usr/local/myshell/greptest | grep -w 1*
花猫 白色 1.8岁 4.2斤

四、文本处理三剑客 — 流编辑器sed

1. 什么是sed

sed是一种流编辑器,它是文本处理中非常重要的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

2. sed命令常用参数

常用命令

函数命令说明
1,n需要操作的行,第一行至第N行
ssearch 查找替换,这个命令使用最多
aappend 添加
iinsert 插入
c替换
d删除行
p打印

还有两个最重要的参数(-n -i)

  1. -n 使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。

  2. -i 直接替换原文件,不加-i都不会修改原文件,只是输出或者放置内存中。

3. sed使用实例

以上都是我亲手测试过才写出来,希望读者可以跟我一起写一遍
(1)、当你将 windows 系统中的文件复制到 linux 后,这个文件每行都会以 \r\n 结尾,sed 可以轻易将其转换为 linux 格式的文件,使用\n 结尾的文件:

#filename.sh 需要将\r\n 结尾替换\n结尾
sed -i 's/\r$//' filename.sh

在这里插入图片描述

1.授权
[root@k8s-master myshell]# chmod +x filename.sh
2.执行,报错
[root@k8s-master myshell]# ./filename.sh 
-bash: ./filename.sh: /bin/bash^M: 坏的解释器: 没有那个文件或目录
[root@k8s-master myshell]# 

以上重现了 当你将 windows 系统中的文件复制到 linux 后,这个文件每行都会以 \r\n 结尾,在linux下是无法执行的。
解决方案

[root@k8s-master myshell]# sed -i 's/\r$//' filename.sh 
# 运行成功
[root@k8s-master myshell]# ./filename.sh 
window下文件和linux区别

(2)、为了方便大家理解,我们创建一个文件来进行解释,请大家消化吸收一下参数的意义

[root@k8s-master myshell]# cat sedtest 
111
222
333
444
555
  1. 输出第3和第5行(p)
[root@k8s-master myshell]# sed -n '3,5p' sedtest 
333
444
555
  1. 输出第3和第5行§,如果不加 -n
[root@k8s-master myshell]# sed '3,5p' sedtest 
111
222
333
333
444
444
555
555
  1. 删除第三至第五行(d), 不修改源文件
[root@k8s-master myshell]# sed '3,5d' sedtest 
111
222
  1. 删除第三至第五行(d), 修改源文件
[root@k8s-master myshell]# sed -i '3,5d' sedtest 
[root@k8s-master myshell]# cat sedtest 
111
222
  1. 第二行替换©为 aaa, 修改源文件
[root@k8s-master myshell]# sed -i '2c aaa' sedtest 
[root@k8s-master myshell]# cat sedtest 
111
aaa
  1. 第二行之前添加(i)ccc, 修改源文件
[root@k8s-master myshell]# sed -i '2i ccc' sedtest 
[root@k8s-master myshell]# cat sedtest 
111
ccc
aaa
  1. 第三行之后添加(a)nnn, 修改源文件
[root@k8s-master myshell]# sed -i '3a nnn' sedtest 
[root@k8s-master myshell]# cat sedtest 
111
ccc
aaa
nnn
  1. 第一行替换©为iii, 修改源文件
[root@k8s-master myshell]# sed -i '1c iii' sedtest 
[root@k8s-master myshell]# cat sedtest 
iii
ccc
aaa
nnn

sed最重要的s命令,查找替换
sed “s/查找/替换/g” g表示一行全部替换,默认一行只替换第一个
9. 将c替换为灿

[root@k8s-master myshell]# sed "s/c/灿/" sedtest 
iii
灿cc
aaa
nnn
  1. 将c全部替换为灿
[root@k8s-master myshell]# sed "s/c/灿/g" sedtest 
iii
灿灿灿
aaa
nnn
  1. 每一行开始加//
[root@k8s-master myshell]# sed "s/^/\/\//g" sedtest 
//iii
//ccc
//aaa
//nnn
  1. 每一行行尾加;
[root@k8s-master myshell]# sed "s/$/;/g" sedtest
iii;
ccc;
aaa;
nnn;
  1. 替换每一行的第二匹配字符a,替换成+
[root@k8s-master myshell]# sed "s/a/+/2" sedtest
iii
ccc
a+a
nnn
  1. 把i替换成我,把n替换成帅
[root@k8s-master myshell]# sed "s/i/我/g;s/n/帅/g" sedtest
我我我
ccc
aaa
帅帅帅

五、文本处理三剑客 — 文本分析工具awk

1. 什么是awk

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,默认以空格为分隔符将每行切片,切开的部分再进行各种分析处理。 awk是行处理器,相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息

awk处理过程: 依次对每一行进行处理,然后输出

2. awk的用法:

awk 参数 ’ BEGIN{} // {action1;action2} ’ END{} 文件名

参数: 
-F   指定分隔符
-f    调用脚本
-v   定义变量
  • Begin{} 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
  • // 匹配代码块,可以是字符串或正则表达式
  • {} 命令代码块,包含一条或多条命令,多条命令用 ; 隔开
  • END{} 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

案例: 统计 /etc/passwd 文件中包含root行的总数

root@k8s-master etc]# awk 'BEGIN{X=0}/root/{X+=1}END{print "I find",X,"root lines"}' /etc/passwd
I find 2 root lines

3. awk中字符的含义:

$0表示整个当前行
$1每行第一个字段
NF字段数量变量
NR每行的记录号,多文件记录递增
FNR与NR类似,不过多文件记录不递增,每个文件都从1开始
\t制表符
\n换行符
FSBEGIN时定义分隔符
RS输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~包含
!~不包含
==等于,必须全部相等,精确比较
!=不等于,精确比较
&&逻辑与
+匹配时表示1个或1个以上
/[0-9][0-9]+/两个或两个以上数字
/[0-9][0-9]*/一个或一个以上数字
OFS输出字段分隔符, 默认也是空格,可以改为其他的
ORS输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F [:#/]定义了三个分隔符

4. awk使用实例

(1)把当前网卡地址都打印出来

[root@k8s-master etc]# ifconfig | awk '{if($1=="inet")print $2}'
10.244.0.1
172.17.0.1
192.168.102.11
10.244.0.0
127.0.0.1

由以上的分析
$1 代表第一行, 等于inet, 输出第二行
在这里插入图片描述
(2) 为了掩饰方便,我选择了使用 /etc/passwd 这个文件来给大家进行演示
在这里插入图片描述

  1. 以:分割,输出 第一行
[root@k8s-master ~]# awk -F: '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
。。。
  1. 以:分割,输出 第一行 和 第二行
[root@k8s-master ~]# awk -F: '{print $1 $2}' /etc/passwd
rootx
binx
daemonx
admx
lpx
。。。
  1. 以:分割, 输出第一、三、六行, 制表符为tab
[root@k8s-master ~]# awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd
root    0       /root
bin     1       /bin
daemon  2       /sbin
adm     3       /var/adm
lp      4       /var/spool/lpd
。。。
  1. 以: 分割, 输出第一、二行, 分行输出
[root@k8s-master ~]# awk -F: '{print $1; print $2}' /etc/passwd
root
x
bin
x
daemon
x
。。。
  1. 显示每行有多少字段
[root@k8s-master ~]# awk -F: '{print NF}' /etc/passwd
7
7
7
7
7
。。。
  1. 打印行数等于5的
[root@k8s-master ~]# awk -F: 'NR==5{print}' /etc/passwd
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  1. 将输出到控制台的数据打印成txt
[root@k8s-master ~]# awk -F: '{print}' /etc/passwd > awktest.txt
[root@k8s-master ~]# ls
1.txt  anaconda-ks.cfg  awktest.txt  first.sh  flannel-v0.11.0-amd64  logs  wr
[root@k8s-master ~]# cat awktest.txt 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
。。。
  1. 打印出含有root的行
[root@k8s-master ~]# awk -F: '/root/{print }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
  1. 打印出文件含有root的行
[root@k8s-master ~]# awk -F: '($1=="root"){print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
  1. 打印出文件中第一个字段是root或ftp的行,与上面的等效
[root@k8s-master ~]# awk -F: '($1=="root"||$1=="ftp"){print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
  1. 如果第一个字段是mail,则打印第一个字段,否则打印第2个字段
[root@k8s-master ~]# awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd
x
x
x
x
x
x
x
x
mail
x
x
x
x
x
x
x
x
x
x
  1. 采用 ps -ef 做为例子继续举例
    在这里插入图片描述
  2. 打印出开头为非root的行
[root@k8s-master ~]# ps -ef | awk '$1!="root" {print}'
UID         PID   PPID  C STIME TTY          TIME CMD
polkitd     769      1  0 5月07 ?       00:00:38 /usr/lib/polkit-1/polkitd --no-debug
chrony      773      1  0 5月07 ?       00:00:00 /usr/sbin/chronyd
dbus        784      1  0 5月07 ?       00:08:12 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
postfix    1227   1221  0 5月07 ?       00:00:00 qmgr -l -t unix -u
postfix    2343   1221  0 11:07 ?        00:00:00 pickup -l -t unix -u
  1. 打印出进程PID大于100000的行数
[root@k8s-master ~]# ps -ef | awk '$2>100000 {print}'
UID         PID   PPID  C STIME TTY          TIME CMD
root     100167      2  0 10:54 ?        00:00:00 [kworker/3:2]
root     105069      2  0 10:56 ?        00:00:00 [kworker/u256:2]
  1. 只打印UID和PID,而且用:连接
[root@k8s-master ~]# ps -ef | awk '{print $1":"$2}'
UID:PID
root:1
root:2
root:4
root:6
root:7
root:8
  1. 各个文件分别计数,行号
[root@k8s-master ~]# ps -ef | awk '{print FNR,$0}'
1 UID         PID   PPID  C STIME TTY          TIME CMD
2 root          1      0  0 5月07 ?       00:04:58 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
3 root          2      0  0 5月07 ?       00:00:00 [kthreadd]
4 root          4      2  0 5月07 ?       00:00:00 [kworker/0:0H]
5 root          6      2  0 5月07 ?       00:01:14 [ksoftirqd/0]
6 root          7      2  0 5月07 ?       00:00:04 [migration/0]
7 root          8      2  0 5月07 ?       00:00:00 [rcu_bh]
8 root          9      2  0 5月07 ?       00:07:13 [rcu_sched]
9 root         10      2  0 5月07 ?       00:00:00 [lru-add-drain]

六、作者有话要说

关于shell、文本处理三剑客grep sed awk,学习的唯一途径,就是多写,先学习基本的用法,然后根据自己的想法,就可以产生无限的可能

本人长期从事java后台开发,如果有疑问请在下方评论,看到就会及时回复

上一篇文章:java8新特性lambda和Stream新手springboot案例2020年新版

大部分的程序员,都是面向百度或者谷歌进行编程的,而网上的资料乱七八糟,有时候找起来让人难受,于是本人无偿进行资料收集的工作,大部分资料都是本人实打实收集的而且测试过,大家不用怀疑准确性,奈何能力有限,免于遗漏,希望读者可以在评论或者私信我,进行改正,大家一起为互联网技术做贡献。

收集资料枯燥无味,如果本文对你有帮助,可以点个赞,这个也是对我最大的鼓励和赞许。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值