学习链接
【尚硅谷】Shell脚本从入门到实战
尚硅谷大数据技术之Shell
Linux文本处理器sed - 视频教程
Linux的sed命令详解大全
你真的懂 sed 命令吗?揭秘 Linux 高效文本处理的神器!
【Shell语言学堂】sed命令最全详解
Linux-文本处理三剑客之grep和正则表达式
linux-文本处理三剑客之sed
Linux-文本处理三剑客之awk
文章目录
第1章 Shell概述
为什么要学习Shell呢?
1)需要看懂运维人员编写的Shell程序。
2)偶尔会编写一些简单Shell程序来管理集群、提高开发效率。
第2章 Shell解析器
(1)Linux提供的Shell解析器有:
[atguigu@hadoop101 ~]$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
(2)bash和sh的关系
[atguigu@hadoop101 bin]$ cd /bin
# sh是bash的软链接
[atguigu@hadoop101 bin]$ ll | grep bash
-rwxr-xr-x. 1 root root 941880 5月 11 2016 bash
lrwxrwxrwx. 1 root root 4 5月 27 2017 sh -> bash
(3)Centos默认的解析器是bash
# 取的环境变量中设置的值, 可通过env|grep SHELL查看
[atguigu@hadoop102 bin]$ echo $SHELL
/bin/bash
第3章 Shell脚本入门
脚本格式
脚本以#!/bin/bash
开头(指定解析器)
第一个Shell脚本:helloworld
(1)需求:创建一个Shell脚本,输出helloworld
(2)案例实操:
[atguigu@hadoop101 datas]$ touch helloworld.sh
[atguigu@hadoop101 datas]$ vi helloworld.sh
在helloworld.sh中输入如下内容
#!/bin/bash
echo "helloworld"
(3)脚本的常用执行方式
第一种:采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)
sh+脚本的相对路径
[atguigu@hadoop101 datas]$ sh helloworld.sh
Helloworld
sh+脚本的绝对路径
[atguigu@hadoop101 datas]$ sh /home/atguigu/datas/helloworld.sh
helloworld
bash+脚本的相对路径
[atguigu@hadoop101 datas]$ bash helloworld.sh
Helloworld
bash+脚本的绝对路径
[atguigu@hadoop101 datas]$ bash /home/atguigu/datas/helloworld.sh
Helloworld
第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)
(a)首先要赋予helloworld.sh 脚本的+x权限
[atguigu@hadoop101 datas]$ chmod 777 helloworld.sh
(b)执行脚本
相对路径
[atguigu@hadoop101 datas]$ ./helloworld.sh
Helloworld
绝对路径
[atguigu@hadoop101 datas]$ /home/atguigu/datas/helloworld.sh
Helloworld
注意:第一种执行方法,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。
第二个Shell脚本:多命令处理
(1)需求:
在/home/atguigu/目录下创建一个banzhang.txt,在banzhang.txt文件中增加“I love cls”。
(2)案例实操:
[atguigu@hadoop101 datas]$ touch batch.sh
[atguigu@hadoop101 datas]$ vi batch.sh
在batch.sh中输入如下内容
#!/bin/bash
cd /home/atguigu
touch cls.txt
echo "I love cls" >>cls.txt
第4章 Shell中的变量
4.1 系统变量
常用系统变量
$HOME
、$PWD
、$SHELL
、$USER
等
案例实操
(1)查看系统变量的值
[atguigu@hadoop101 datas]$ echo $HOME
/home/atguigu
(2)显示当前Shell中所有变量:set
[atguigu@hadoop101 datas]$ set
BASH=/bin/bash
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
...省略
4.2 自定义变量
1.基本语法
(1)定义变量:变量=值 (注意两侧不能有空格)
(2)撤销变量:unset 变量(注意不能对静态变量unset)
(3)声明静态变量:readonly变量,注意:不能unset
2.变量定义规则
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
(2)等号两侧不能有空格
(3)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
(4)变量的值如果有空格,需要使用双引号或单引号括起来。
案例实操
(1)定义变量A
# 注意两侧不能有空格
[atguigu@hadoop101 datas]$ A=5
[atguigu@hadoop101 datas]$ echo $A
5
(2)给变量A重新赋值
[atguigu@hadoop101 datas]$ A=8
[atguigu@hadoop101 datas]$ echo $A
8
(3)撤销变量A
[atguigu@hadoop101 datas]$ unset A
# 输出了个换行
[atguigu@hadoop101 datas]$ echo $A
(4)声明静态的变量B=2,不能unset,也不能被重新赋值
[atguigu@hadoop101 datas]$ readonly B=2
[atguigu@hadoop101 datas]$ echo $B
2
[atguigu@hadoop101 datas]$ B=9
-bash: B: readonly variable
[atguigu@hadoop101]$ readonly B=4
-bash: B: readonly variable
[atguigu@hadoop101 datas]$ unset B
-bash: unset B: can not unset: readonly variable
[atguigu@hadoop101 datas]$
[atguigu@hadoop101 datas]$
[atguigu@hadoop101 datas]$ echo $BC
[atguigu@hadoop101 datas]$ echo ${B}C
9C
(5)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
[atguigu@hadoop102 ~]$ C=1+2
[atguigu@hadoop102 ~]$ echo $C
1+2
(6)变量的值如果有空格,需要使用双引号或单引号括起来
[atguigu@hadoop102 ~]$ D=I love banzhang
-bash: world: command not found
[atguigu@hadoop102 ~]$ D="I love banzhang"
[atguigu@hadoop102 ~]$ echo $D
I love banzhang
(7)可把变量提升为全局环境变量,可供其他Shell程序使用
export 变量名
(也可以使用export 变量名=变量值
)
[atguigu@hadoop101 datas]$ vim helloworld.sh
在helloworld.sh文件中增加echo $B
#!/bin/bash
echo "helloworld"
echo $B
[atguigu@hadoop101 datas]$ ./helloworld.sh
Helloworld
发现并没有打印输出变量B的值。
[atguigu@hadoop101 datas]$ echo $B
2
[atguigu@hadoop101 datas]$ export B
[atguigu@hadoop101 datas]$ ./helloworld.sh
helloworld
2
4.3 特殊变量:$n
1.基本语法
$n
(功能描述:n为数字,$0
代表该脚本名称,$1
-$9
代表第一到第九个参数,十及以上的参数需要用大括号包含,如${10}
)
2.案例实操
输出该脚本文件名称、输入参数1和输入参数2 的值
[atguigu@hadoop101 datas]$ touch param.sh
[atguigu@hadoop101 datas]$ vim param.sh
在脚本中输入如下
#!/bin/bash
echo $0
echo '$0'
echo "$0"
echo "\$0"
echo "$0 $1 $2"
echo "\$0 $1 $2"
[atguigu@hadoop101 datas]$ chmod 777 param.sh
[atguigu@hadoop101 datas]$ sh param.sh a b c
param.sh
$0
param.sh
$0
param.sh a b
$0 a b
4.4 特殊变量:$#
1.基本语法
$#
(功能描述:获取所有输入参数个数,常用于循环)
2.案例实操
获取输入参数的个数
[atguigu@hadoop101 datas]$ vim param.sh
#!/bin/bash
echo "$0 $1 $2"
echo $#
[atguigu@hadoop101 datas]$ chmod 777 param.sh
[atguigu@hadoop101 datas]$ ./param.sh a b
parameter.sh a b
2
4.5 特殊变量:$*、$@
1.基本语法
$*
(功能描述:这个变量代表命令行中所有的参数,$*
把所有的参数看成一个整体)
$@
(功能描述:这个变量代表命令行中所有的参数,$@
把每个参数区分对待)
2.案例实操
打印输入的所有参数
[atguigu@hadoop101 datas]$ vim param.sh
#!/bin/bash
echo "$0 $1 $2"
echo $#
echo $*
echo $@
[atguigu@hadoop101 datas]$ ./param.sh 1 2 3
./param.sh 1 2
3
1 2 3
1 2 3
4.6 特殊变量:$?
1.基本语法
$?
(功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。)
2.案例实操
(1)判断helloworld.sh脚本是否正确执行
[atguigu@hadoop101 datas]$ ./helloworld.sh
helloworld
[atguigu@hadoop101 datas]$ $?
-bash: 0: command not found
[atguigu@hadoop101 datas]$ echo $?
127
[atguigu@hadoop101 datas]$ ./helloworld.sh
hello world
[atguigu@hadoop101 datas]$ echo $?
0
第5章 运算符
1.基本语法
(1)$((运算式))
或$[运算式]
(2)expr + , - , \*, /, % 加,减,乘,除,取余。如:expr 1 + 2
注意:expr运算符间必须要有空格
2.案例实操
(1)计算3+2的值
[atguigu@hadoop101 datas]$ expr 2+3
2+3
[atguigu@hadoop101 datas]$ expr 2 + 3
5
(2)计算3-2的值
[atguigu@hadoop101 datas]$ expr 3 - 2
1
(3)计算(2+3)X4的值
[atguigu@hadoop101 datas]$ expr `expr 2 + 3` \* 4
20
[atguigu@hadoop101 datas]$ S=$[(2+3)*4]
[atguigu@hadoop101 datas]$ echo $S
20
[atguigu@hadoop101 datas]$ k=$[(2 + 3) * 4]
[atguigu@hadoop101 datas]$ echo $k
20
[atguigu@hadoop101 datas]$ q=$[ ( 2 +3 )* 4]
[atguigu@hadoop101 datas]$ echo $q
20
第6章 条件判断
1.基本语法
[ condition ]
(注意condition前后要有空格)
注意:条件非空即为true,[ atguigu ]返回true,[] 返回false。
2. 常用判断条件
(1)两个整数之间比较
= 字符串比较
-lt 小于(less than) -le 小于等于(less equal)
-eq 等于(equal) -gt 大于(greater than)
-ge 大于等于(greater equal) -ne 不等于(Not equal)
(2)按照文件权限进行判断
-r 有读的权限(read) -w 有写的权限(write)
-x 有执行的权限(execute)
(3)按照文件类型进行判断
-f 文件存在并且是一个常规的文件(file)
-e 文件存在(existence) -d 文件存在并是一个目录(directory)
3.案例实操
(1)23是否大于等于22
[atguigu@hadoop101 datas]$ [ 23 -ge 22 ]
# 输出0, 表示上一条命令执行是成功的
[atguigu@hadoop101 datas]$ echo $?
0
[atguigu@hadoop101 datas]$ [ 23 -le 22 ]
# 非0, 表示上一条命令执行是失败的
[atguigu@hadoop101 datas]$ echo $?
1
(2)helloworld.sh是否具有写权限
[atguigu@hadoop101 datas]$ [ -w helloworld.sh ]
[atguigu@hadoop101 datas]$ echo $?
0
(3)/home/atguigu/cls.txt目录中的文件是否存在
[atguigu@hadoop101 datas]$ [ -e /home/atguigu/cls.txt ]
[atguigu@hadoop101 datas]$ echo $?
1
(4)多条件判断
(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
[atguigu@hadoop101 ~]$ [ condition ] && echo OK || echo notok
OK
[atguigu@hadoop101 datas]$ [ condition ] && [ ] || echo notok
notok
第7章 流程控制
7.1 if 判断
1.基本语法
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
注意事项:
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
(2)if后要有空格
2.案例实操
输入一个数字,根据不同情况判断,输出结果
[atguigu@hadoop101 datas]$ touch if.sh
[atguigu@hadoop101 datas]$ vim if.sh
#!/bin/bash
if [ $1 -eq 1 ];then
# 这里使用单引号取不了值
echo '原来是个1,$1'
elif [ $1 -eq "2" ]
then
echo "原来是个2"
else
# 注意这里要用双引号才能取到值
echo "不是1也不是2,而是$1"
fi
[atguigu@hadoop101 datas]$ chmod 777 if.sh
[root@hadoop101 datas]$ sh if.sh
if.sh: 第 2 行:[: -eq: 期待一元表达式
if.sh: 第 5 行:[: -eq: 期待一元表达式
不是1也不是2,而是
[root@hadoop101 datas]$ sh if.sh 1
原来是个1,$1
[root@hadoop101 datas]$ sh if.sh 2
原来是个2
[root@hadoop101 datas]$ sh if.sh 3
不是1也不是2,而是3
[root@hadoop101 datas]$ sh if.sh 4
不是1也不是2,而是4
[root@hadoop101 datas]$
7.2 case 语句
1.基本语法
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意事项:
-
case行尾必须为单词
in
,每一个模式匹配必须以右括号)
结束。 -
双分号
;;
表示命令序列结束,相当于java中的break。 -
最后的
*)
表示默认模式,相当于java中的default。
2.案例实操
(1)输入一个数字,如果是1,则输出banzhang,如果是2,则输出cls,如果是其它,输出renyao。
[atguigu@hadoop101 datas]$ touch case.sh
[atguigu@hadoop101 datas]$ vim case.sh
#!/bin/bash
case $1 in
'1')
echo '是个1,$1'
;;
"2")
echo "是个2,$1"
;;
3)
echo "是个3,${1}abcd"
;;
*)
echo "是个啥?$1"
;;
esac
[atguigu@hadoop101 datas]$ sh case.sh 1
是个1,$1
[atguigu@hadoop101 datas]$ sh case.sh 2
是个2,2
[atguigu@hadoop101 datas]$ sh case.sh 3
是个3,3abcd
[atguigu@hadoop101 datas]$ sh case.sh 4
是个啥?4
[atguigu@hadoop101 datas]$ datas sh case.sh
是个啥?
7.3 for 循环
1.基本语法1
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
案例实操
(1)从1加到100
[atguigu@hadoop101 datas]$ touch for1.sh
[atguigu@hadoop101 datas]$ vim for1.sh
#!/bin/bash
s=0
for((i=0;i<=100;i++))
do
# 要取变量的值, 就得使用$去取, 因此$i就是取得变量i对应的值
s=$[$s+$i]
done
echo "结果是: $s"
[atguigu@hadoop101 datas]$ chmod 777 for1.sh
[atguigu@hadoop101 datas]$ ./for1.sh
结果是: 5050
2.基本语法2
for 变量 in 值1 值2 值3…
do
程序
done
案例实操
使用$*
打印所有输入参数
[atguigu@hadoop101 datas]$ touch for2.sh
[atguigu@hadoop101 datas]$ vim for2.sh
#!/bin/bash
for i in $*
do
echo "我是: $i"
done
[atguigu@hadoop101 datas]$ sh for2.sh a b c
我是: a
我是: b
我是: c
使用$@
打印所有输入参数
[atguigu@hadoop101 datas]$ touch for2.sh
[atguigu@hadoop101 datas]$ vim for2.sh
#!/bin/bash
for i in $@
do
echo "我是: $i"
done
[atguigu@hadoop101 datas]$ sh for2.sh a b c
我是: a
我是: b
我是: c
使用"$*"
打印所有输入参数
[atguigu@hadoop101 datas]$ touch for2.sh
[atguigu@hadoop101 datas]$ vim for2.sh
#!/bin/bash
# 会把所有的参数都封装成1个, 这里只循环了1次
for i in "$*"
do
echo "我是: $i"
done
[atguigu@hadoop101 datas]$ sh for2.sh a b c
我是: a b c
使用"$@"
打印所有输入参数
[atguigu@hadoop101 datas]$ touch for2.sh
[atguigu@hadoop101 datas]$ vim for2.sh
#!/bin/bash
for i in "$@"
do
echo "我是: $i"
done
[atguigu@hadoop101 datas]$ sh for2.sh a b c
我是: a
我是: b
我是: c
7.4 while 循环
1.基本语法
while [ 条件判断式 ]
do
程序
done
2.案例实操
(1)从1加到100
[atguigu@hadoop101 datas]$ touch while.sh
[atguigu@hadoop101 datas]$ vim while.sh
#!/bin/bash
s=0
i=1
while [ $i -le 100 ] # 100 这里加上双引号或者单引号, 结果也是一样的
do
s=$[$s + $i]
i=$[$i + 1]
done
echo "结果是: $s,${s}"
[atguigu@hadoop101 datas]$ chmod 777 while.sh
[atguigu@hadoop101 datas]$ ./while.sh
结果是: 5050,5050
第8章 read读取控制台输入
1.基本语法
read(选项)(参数)
选项:
-
-p:指定读取值时的提示符;
-
-t:指定读取值时等待的时间(秒)。
参数
- 变量:指定读取值的变量名
2.案例实操
(1)提示7秒内,读取控制台输入的名称
[atguigu@hadoop101 datas]$ touch read.sh
[atguigu@hadoop101 datas]$ vim read.sh
#!/bin/bash
read -t 7 -p "Enter your name in 7 seconds: " NAME
echo $NAME
[atguigu@hadoop101 datas]$ ./read.sh
Enter your name in 7 seconds: shell
shell
第9章 函数
9.1 系统函数
1.basename基本语法
basename [string / pathname] [suffix]
- 功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
选项:
- suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
案例实操
[atguigu@hadoop101 datas]$ basename /home/atguigu/if.sh
if.sh
[atguigu@hadoop101 datas]$ basename /home/atguigu/if.sh .sh
if
[atguigu@hadoop101 datas]$ a=`basename /home/atguigu/if.sh .sh`
[atguigu@hadoop101 datas]$ $a
if
2. dirname基本语法
dirname 文件绝对路径
- 功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
案例实操
获取banzhang.txt文件的路径
[atguigu@hadoop101 ~]$ dirname /home/atguigu/if.sh
/home/atguigu
9.2 自定义函数
1.基本语法
[ function ] funname[()]
{
Action;
[return int;]
}
funname
注意事项
(1)必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
(2)函数返回值,只能通过$?
系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
案例实操
计算两个输入参数的和
[atguigu@hadoop101 datas]$ touch sum.sh
[atguigu@hadoop101 datas]$ vim sum.sh
#!/bin/bash
function sum()
{
s=0
s=$[$1 + $2]
echo $s
}
read -p '请输入第1个数:' n1
read -p "请输入第2个数:" n2
sum $n1 $n2;
[atguigu@hadoop101 datas]$ chmod 777 sum.sh
[atguigu@hadoop101 datas]$ ./sum.sh
请输入第1个数:1
请输入第2个数:2
3
第10章 Shell工具
10.1 cut
cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。
- cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
1.基本用法
cut [选项参数] filename
说明:默认分隔符是制表符
2.选项参数说明
选项参数 | 功能 |
---|---|
-f | 列号,提取第几列 |
-d | 分隔符,按照指定分隔符分割列 |
3.案例实操
(0)数据准备
[atguigu@hadoop101 datas]$ touch cut.txt
[atguigu@hadoop101 datas]$ vim cut.txt
aaa 111
bbb 222
ccc 333 # 2个空格
ddd 444 # 2个空格
eee 555 # 2个空格
(1)切割cut.txt 中的1列
[atguigu@hadoop101 datas]$ cut -d " " -f 1 cut.txt
aaa
bbb
ccc
ddd
eee
[atguigu@hadoop101 datas]$ cut -d " " -f 2 cut.txt
111
222
[atguigu@hadoop101 datas]$ cut -d " " -f 3 cut.txt
333
444
555
[root@localhost data]$ cat cut2.txt
1 2 # 中间有5个空格
[root@localhost data]$ cut -d " " -f 1 cut2.txt
1
[root@localhost data]$ cut -d " " -f 2 cut2.txt
[root@localhost data]$ cut -d " " -f 3 cut2.txt
[root@localhost data]$ cut -d " " -f 4 cut2.txt
[root@localhost data]$ cut -d " " -f 5 cut2.txt
[root@localhost data]$ cut -d " " -f 6 cut2.txt
2
[root@localhost data]$ cat cut2.txt
1 2
(2)切割cut.txt第二、三列
[atguigu@hadoop101 datas]$ cut -d " " -f 2,3 cut.txt
111
222
333
444
555
(3)在cut.txt文件中切割出guan
[atguigu@hadoop101 datas]$ cat cut.txt | grep "bbb" | cut -d " " -f 1
bbb
(4)选取系统PATH变量值,第2个“:”开始后的所有路径:
[atguigu@hadoop101 datas]$ echo $PATH
/usr/lib/jvm/jdk1.8.0_221/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/rocketmq/rocketmq-all-4.4.0-bin-release/bin:/root/bin
# 其中: 1、冒号两侧可以不用双引号, 2、3-表示从第三列开始到后面所有列
[atguigu@hadoop101 datas]$ echo $PATH | cut -d ":" -f 3-
/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/rocketmq/rocketmq-all-4.4.0-bin-release/bin:/root/bin
(5)切割ifconfig 后打印的IP地址
[atguigu@hadoop101 datas]$ ifconfig eth0 | grep "inet addr" | cut -d : -f 2 | cut -d" " -f 1
192.168.1.102
10.2 sed
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
1. 基本用法
sed [选项参数] ‘command’ filename
2. 选项参数说明
选项参数 | 功能 |
---|---|
-e | 直接在指令列模式上进行sed的动作编辑。 |
3. 命令功能描述
命令 | 功能描述 |
---|---|
a | 新增,a的后面可以接字串,在下一行出现 |
d | 删除 |
s | 查找并替换 |
4.案例实操
(0)数据准备
[root@zzhua data]$ cat sed.txt
aaa 111
bbb 222
ccc 333
ddd 444
eee 555
(1)将"hello world"这个词语插入到sed.txt第二行下,打印(注意:不会修改原文件)。
[root@zzhua data]$ sed "2a hello world" sed.txt
aaa 111
bbb 222
hello world
ccc 333
ddd 444
eee 555
(2)删除sed.txt文件所有包含ccc的行
[root@zzhua data]$ sed "/ccc/d" sed.txt
aaa 111
bbb 222
ddd 444
eee 555
[root@zzhua data]$ sed "/cc/d" sed.txt
aaa 111
bbb 222
ddd 444
eee 555
(3)将sed.txt文件中c替换为z(注意:g表示global,全部替换)
[root@zzhua data]$ sed "s/c/z/" sed.txt
aaa 111
bbb 222
zcc 333
ddd 444
eee 555
[root@zzhua data]$ sed "s/c/z/g" sed.txt
aaa 111
bbb 222
zzz 333
ddd 444
eee 555
(4)将sed.txt文件中的第二行删除,并将cc替换为z
[root@zzhua data]$ sed -e '2d' -e 's/cc/z/g' sed.txt
aaa 111
zc 333
ddd 444
eee 555
10.3 awk
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
1.基本用法
awk [选项参数] ‘pattern1{action1} pattern2{action2}…’ filename
-
pattern:表示AWK在数据中查找的内容,就是匹配模式
-
action:在找到匹配内容时所执行的一系列命令
2.选项参数说明
选项参数 | 功能 |
---|---|
-F | 指定输入文件折分隔符 |
-v | 赋值一个用户定义变量 |
3.案例实操
(0)数据准备
[root@zzhua data]$ cp /etc/passwd ./
(1)搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。
[root@zzhua data]$ awk '/^root/{print}' passwd
root:x:0:0:root:/root:/bin/bash
[root@zzhua data]$ awk -F : '/^root/{print $7}' passwd
/bin/bash
(2)搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。(注意:只有匹配了pattern的行才会执行action)
[root@zzhua data]$ awk -F : '/^root/{print $1","$7}' passwd
root,/bin/bash
(3)只显示/etc/passwd的第一列和第七列,以逗号分割,且在第一行前面添加列名user,shell在最后一行添加"halo world"。(注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。)
[root@zzhua data]$ awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "halo wolrd"}' passwd
user, shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
halt,/sbin/halt
mail,/sbin/nologin
operator,/sbin/nologin
games,/sbin/nologin
ftp,/sbin/nologin
nobody,/sbin/nologin
systemd-network,/sbin/nologin
dbus,/sbin/nologin
polkitd,/sbin/nologin
libstoragemgmt,/sbin/nologin
colord,/sbin/nologin
rpc,/sbin/nologin
saned,/sbin/nologin
saslauth,/sbin/nologin
abrt,/sbin/nologin
setroubleshoot,/sbin/nologin
rtkit,/sbin/nologin
pulse,/sbin/nologin
chrony,/sbin/nologin
unbound,/sbin/nologin
radvd,/sbin/nologin
tss,/sbin/nologin
usbmuxd,/sbin/nologin
geoclue,/sbin/nologin
qemu,/sbin/nologin
gluster,/sbin/nologin
gdm,/sbin/nologin
rpcuser,/sbin/nologin
nfsnobody,/sbin/nologin
gnome-initial-setup,/sbin/nologin
sshd,/sbin/nologin
avahi,/sbin/nologin
postfix,/sbin/nologin
ntp,/sbin/nologin
tcpdump,/sbin/nologin
zzhua,/bin/bash
halo wolrd
(4)将passwd文件中的用户id增加数值1并输出
[root@zzhua data]$ awk -v i=1 -F: '{print $3+i}' passwd
1
2
3
4
5
6
7
8
9
12
13
15
100
193
82
1000
999
998
33
997
996
174
995
173
172
994
993
76
60
114
992
108
991
43
30
65535
990
75
71
90
39
73
1001
4.awk的内置变量
变量 | 说明 |
---|---|
FILENAME | 文件名 |
NR | 已读的记录数 |
NF | 浏览记录的域的个数(切割后,列的个数) |
5.案例实操
(1)统计passwd文件名,每行的行号,每行的列数
[root@zzhua data]$ awk -F: '{print "filename:" FILENAME ", linenumber:" NR ",columns:" NF}' passwd
filename:passwd, linenumber:1,columns:7
filename:passwd, linenumber:2,columns:7
filename:passwd, linenumber:3,columns:7
filename:passwd, linenumber:4,columns:7
filename:passwd, linenumber:5,columns:7
filename:passwd, linenumber:6,columns:7
filename:passwd, linenumber:7,columns:7
filename:passwd, linenumber:8,columns:7
filename:passwd, linenumber:9,columns:7
filename:passwd, linenumber:10,columns:7
filename:passwd, linenumber:11,columns:7
filename:passwd, linenumber:12,columns:7
filename:passwd, linenumber:13,columns:7
filename:passwd, linenumber:14,columns:7
filename:passwd, linenumber:15,columns:7
filename:passwd, linenumber:16,columns:7
filename:passwd, linenumber:17,columns:7
filename:passwd, linenumber:18,columns:7
filename:passwd, linenumber:19,columns:7
filename:passwd, linenumber:20,columns:7
filename:passwd, linenumber:21,columns:7
filename:passwd, linenumber:22,columns:7
filename:passwd, linenumber:23,columns:7
filename:passwd, linenumber:24,columns:7
filename:passwd, linenumber:25,columns:7
filename:passwd, linenumber:26,columns:7
filename:passwd, linenumber:27,columns:7
filename:passwd, linenumber:28,columns:7
filename:passwd, linenumber:29,columns:7
filename:passwd, linenumber:30,columns:7
filename:passwd, linenumber:31,columns:7
filename:passwd, linenumber:32,columns:7
filename:passwd, linenumber:33,columns:7
filename:passwd, linenumber:34,columns:7
filename:passwd, linenumber:35,columns:7
filename:passwd, linenumber:36,columns:7
filename:passwd, linenumber:37,columns:7
filename:passwd, linenumber:38,columns:7
filename:passwd, linenumber:39,columns:7
filename:passwd, linenumber:40,columns:7
filename:passwd, linenumber:41,columns:7
filename:passwd, linenumber:42,columns:7
filename:passwd, linenumber:43,columns:7
(2)切割IP
[atguigu@hadoop102 datas]$ ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}'
192.168.1.102
(3)查询sed.txt中空行所在的行号
[atguigu@hadoop102 datas]$ awk '/^$/{print NR}' sed.txt
5
10.4 sort
sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。
1.基本语法
sort(选项)(参数)
选项 | 说明 |
---|---|
-n | 依照数值的大小排序 |
-r | 以相反的顺序来排序 |
-t | 设置排序时所用的分隔字符 |
-k | 指定需要排序的列 |
参数:指定待排序的文件列表
2. 案例实操
(0)数据准备
[atguigu@hadoop102 datas]$ touch sort.sh
[atguigu@hadoop102 datas]$ vim sort.sh
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6
(1)按照“:”分割后的第三列倒序排序。
[atguigu@hadoop102 datas]$ sort -t : -nrk 3 sort.sh
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6
10.5 wc
wc命令用来统计文件信息。利用wc指令我们可以计算文件的行数,字节数、字符数等。
1)基本语法
wc [选项参数] filename
选项参数 | 功能 |
---|---|
-l | 统计文件行数 |
-w | 统计文件的单词数 |
-m | 统计文件的字符数 |
-c | 统计文件的字节数 |
2)案例实操
统计/etc/profile文件的行数、单词数、字节数!
[atguigu@hadoop101 datas]$ wc -l /etc/profile
[atguigu@hadoop101 datas]$ wc -w /etc/profile
[atguigu@hadoop101 datas]$ wc -m /etc/profile
第11章 企业真实面试题
11.1 京东
问题1:使用Linux命令查询file1中空行所在的行号
[atguigu@hadoop102 datas]$ awk '/^$/{print NR}' sed.txt
5
问题2:有文件chengji.txt内容如下:
张三 40
李四 50
王五 60
使用Linux命令计算第二列的和并输出
[atguigu@hadoop102 datas]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'
150
11.2 搜狐&和讯网
问题1:Shell脚本里如何检查一个文件是否存在?如果不存在该如何处理?
#!/bin/bash
if [ -f file.txt ]; then
echo "文件存在!"
else
echo "文件不存在!"
fi
11.3 新浪
问题1:用shell写一个脚本,对文本中无序的一列数字排序
[root@CentOS6-2 ~]$ cat test.txt
9
8
7
6
5
4
3
2
10
1
[root@CentOS6-2 ~]$ sort -n test.txt|awk '{a+=$0;print $0}END{print "SUM="a}'
1
2
3
4
5
6
7
8
9
10
SUM=55
11.3 金和网络
问题1:请用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”shen”的文件名称
[atguigu@hadoop102 datas]$ grep -r "shen" /home | cut -d ":" -f 1
/home/atguigu/datas/sed.txt
/home/atguigu/datas/cut.txt