大数据开发的shell入门

shell概述

为什么要学习shell呢?
(1)需要看懂运维人员写的shell程序。
(2)偶尔会编写一些简单shell程序来管理集群、提高开发效率。

shell概述

shell是一个命令行解释器,他接受应用程序/用户命令,然后调用操作系统内核。
在这里插入图片描述

shell解释器

  1. Linux提供的shell解析器有:
[root@bogon bin]# cat /etc/shells 
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
[root@bogon bin]# 
  1. bash和sh的关系:
[root@bogon ~]# cd /bin/
[root@bogon bin]# ll | grep bash
-rwxr-xr-x. 1 root root     964536 41 2020 bash
lrwxrwxrwx. 1 root root         10 219 04:07 bashbug -> bashbug-64
-rwxr-xr-x. 1 root root       6964 41 2020 bashbug-64
lrwxrwxrwx. 1 root root          4 219 04:07 sh -> bash
  1. Centos默认的解析器是bash:
[root@bogon bin]#  echo $SHELL
/bin/bash
[root@bogon bin]# 

shell脚本入门

  1. 脚本格式

脚本以#!/bin/bash开头(指定解释器)

  1. 第一个shell脚本:helloworld
    (1) 需求:创建一个shell脚本,输出helloworld
    (2)案例实操:
[root@bogon work]# mkdir datas
[root@bogon work]# cd datas/
[root@bogon datas]# ls
[root@bogon datas]# touch hellotest.sh
[root@bogon datas]# vim hellotest.sh 
[root@bogon datas]# cat hellotest.sh 
#!/bin/bash
echo "helloworld!!"
[root@bogon datas]# chmod -R +x hellotest.sh 
[root@bogon datas]# ls -l
总用量 4
-rwxr-xr-x. 1 root root 32 221 11:44 hellotest.sh
[root@bogon datas]# ./hellotest.sh 
helloworld!!
[root@bogon datas]# 

	(3)脚本的常用执行方式:
	第一种:采用bash或sh+脚本的相对路径或者绝对路径(不用赋予脚本+x权限)
  • sh + 脚本的相对路径
[root@bogon datas]# sh hellotest.sh 
helloworld!!
  • sh + 脚本的绝对路径
[root@bogon datas]# sh /opt/work/datas/hellotest.sh 
helloworld!!
  • bash + 脚本的相对路径
[root@bogon datas]# bash hellotest.sh 
helloworld!!
  • bash + 脚本的绝对路径
[root@bogon datas]# bash /opt/work/datas/hellotest.sh 
helloworld!!
	第二种:采用输入脚本的绝对路径或相对路径执行脚本(`必须具有可执行权限+x`)
	(a)首先赋予hellotest.sh脚本的+x权限
	(b)执行脚本
[root@bogon datas]# ./hellotest.sh
-bash: ./hellotest.sh: 权限不够
[root@bogon datas]# ls -l
总用量 4
-rw-r--r--. 1 root root 32 221 11:44 hellotest.sh
  • 执行脚本,相对路径和绝对路径
[root@bogon datas]# chmod -R +x hellotest.sh 
[root@bogon datas]# ls -l
总用量 4
-rwxr-xr-x. 1 root root 32 221 11:44 hellotest.sh
[root@bogon datas]# ./hellotest.sh 
helloworld!!
[root@bogon datas]# /opt/work/datas/hellotest.sh 
helloworld!!
[root@bogon datas]#

注意:第一种执行方式,本质是bash解释器帮你执行脚本,所以脚本本身不需要执行权限。第二种方式,本质是脚本需要自己执行,所以需要执行权限。

  1. 第二个shell脚本:多命令处理
    (1)需求:
    在/opt/work/datas目录下创建一个banzhuan.txt,在banzhuan.txt文件中增加“I love work”。
    (2)案例实操:
[root@bogon datas]# vim bash.sh
[root@bogon datas]# cat bash.sh 
#!/bin/bash
cd /opt/work/datas/
touch banzhuan.txt
echo "I love work" >> banzhuan.txt
cat banzhuan.txt
[root@bogon datas]# ls
bash.sh
[root@bogon datas]# bash bash.sh 
I love work
[root@bogon datas]# ls
banzhuan.txt  bash.sh
[root@bogon datas]# 

shell中的变量

系统变量

  1. 常用系统变量

$HOME、$PWD、$SHELL、$USER等

  1. 案例实操
    (1)查看系统变量的值
[root@bogon datas]# echo $HOME
/root
[root@bogon datas]# echo $SHELL
/bin/bash
[root@bogon datas]# echo $PWD
/opt/work/datas
[root@bogon datas]# echo $USER
root

(2)显示当前shell中所有的变量:set

set,输出所有变量,包括全局变量、局部变量
env,只显示全局变量
declare,输出所有的变量,如同set
export,显示和设置环境变量值

自定义变量

  1. 基本语法
    (1)定义变量:变量=值
    (2)撤销变量:unset
    (3)声明静态变量:readonly变量,注意:不能unset

  2. 变量定义规则
    (1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写
    (2)定义变量时,等号两侧不能有空格。
    (3)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
    (4)变量的值如果有空格需要使用双引号或单引号括起来

  3. 案例实操
    (1)定义变量A

[root@bogon datas]# A=1
[root@bogon datas]# echo $A
1
[root@bogon datas]# A = 2
bash: A: 未找到命令...
[root@bogon datas]# A= 0
bash: 0: 未找到命令...
[root@bogon datas]# A=0
[root@bogon datas]# echo $A
0

(2)撤销变量A

[root@bogon datas]# unset A
[root@bogon datas]# echo $A

[root@bogon datas]# 

(3)声明静态的变量B=2,不能unset。

[root@bogon datas]# readonly B=2
[root@bogon datas]# echo $B
2
[root@bogon datas]# B=9
-bash: B: 只读变量
[root@bogon datas]# unset B
-bash: unset: B: 无法反设定: 只读 variable

(4)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。

[root@bogon datas]# C=1+2
[root@bogon datas]# echo $C
1+2
[root@bogon datas]# 

(5)变量的值如果有空格,需要使用双引号或单引号括起来

[root@bogon datas]# D=I love banzhuan
bash: love: 未找到命令...
[root@bogon datas]# D="I love banzhuan"
[root@bogon datas]# echo $D
I love banzhuan
[root@bogon datas]# 

(6)可把变量提升为全局环境变量,可供其他shell程序使用。

  • export 变量名
    在hellotest.sh文件中增加echo $B
[root@bogon datas]# cat hellotest.sh 
#!/bin/bash
echo "helloworld!!"
[root@bogon datas]# vim hellotest.sh 
[root@bogon datas]# cat hellotest.sh 
#!/bin/bash
echo "helloworld!!"
echo $B
[root@bogon datas]# ./hellotest.sh 
helloworld!!

[root@bogon datas]# echo $B
2
 [root@bogon datas]#

发现并没有打印输出变量B的值。使用export升级B变量的作用域。

[root@bogon datas]# export B
[root@bogon datas]# ./hellotest.sh 
helloworld!!
2
[root@bogon datas]#

特殊变量:$n

  1. 基本语法

$n (功能描述:n为数字,$0代表该脚本的名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如:${10})

  1. 案例实操
    (1)输出该脚本文件名称、输入参数1和输入参数2的值。
[root@bogon datas]# touch parameter.sh
[root@bogon datas]# vim parameter.sh 
[root@bogon datas]# cat parameter.sh 
#!/bin/bash
echo "$0 $1 $2 $3 $4 $5"
[root@bogon datas]# bash parameter.sh 
parameter.sh     
[root@bogon datas]# bash parameter.sh shuzi 
parameter.sh shuzi    
[root@bogon datas]# bash parameter.sh wang zhang li liu qi zhao
parameter.sh wang zhang li liu qi
[root@bogon datas]#

特殊变量:$#

  1. 基本语法

$# (功能描述:获取所有输入参数个数,常用于循环)。

  1. 案例操作
    (1)获取输入参数的个数:($#:输出的是传入最后一个参数的索引下标id
[root@bogon datas]# cat parameter.sh 
#!/bin/bash
echo "$0 $1 $2 $3 $4 $5"
echo "$#"
[root@bogon datas]# bash parameter.sh 
parameter.sh     
0
[root@bogon datas]# bash parameter.sh wang zhang li liu qi zhao
parameter.sh wang zhang li liu qi
6
[root@bogon datas]# bash parameter.sh wang zhang li liu qi zhao qiu hu
parameter.sh wang zhang li liu qi
8
[root@bogon datas]# bash parameter.sh wang zhang li liu qi zhao qiu hu op qw
parameter.sh wang zhang li liu qi
10
[root@bogon datas]# 

特殊变量:$*、$@

  1. 基本语法

$* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)。
$@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分别对待,会换行处输出参数)。

  1. 案例操作
    (1)打印输入的所有参数
[root@bogon datas]# vim parameter.sh 
[root@bogon datas]# cat parameter.sh 
#!/bin/bash
echo "$0 $1 $2 $3 $4 $5"
echo $#
echo $*
echo $@
[root@bogon datas]# bash parameter.sh 
parameter.sh     
0


[root@bogon datas]# bash parameter.sh  java
parameter.sh java    
1
java
java
[root@bogon datas]# bash parameter.sh  java python
parameter.sh java python   
2
java python
java python
[root@bogon datas]# bash parameter.sh  java python go
parameter.sh java python go  
3
java python go
java python go
[root@bogon datas]# 

特殊变量:$?

  1. 基本语法

$? (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,则证明上一个命令正确执行,如果这个变量的值为非0【具体是哪个数值,由命令自己来决定】,则证明上一个命令执行不正确了。)

  1. 案例操作
    (1)判断hellotest.sh脚本是否正确执行。
[root@bogon datas]# ./hellotest.sh 
helloworld!!
2
[root@bogon datas]# echo $?
0
[root@bogon datas]# ecgfs
bash: ecgfs: 未找到命令...
[root@bogon datas]# echo $?
127
[root@bogon datas]#

运算符

  1. 基本语法
    (1)“$((运算式))”或“$[运算式]”
    (2)expr +、-、\*、/、% — 加,减,乘,除,取余
    注意:expr运算符间要有空格
  2. 案例操作
    (1)计算3+2的值。
[root@bogon datas]# expr 3+2
3+2
[root@bogon datas]# expr 3 +2
expr: 语法错误
[root@bogon datas]# expr 3 + 2
5

(2)计算3-2的值。

[root@bogon datas]# expr 3 - 2
1
[root@bogon datas]# 

(3)计算(3-2)x4的值
- (a)expr一步完成计算

[root@bogon datas]# expr `expr 3 + 2` \* 4
20
[root@bogon datas]# 

(b)采用$[运算式]方式

[root@bogon datas]# s=$[(2+3)*4]
[root@bogon datas]# echo $s
20
[root@bogon datas]# 

条件判断

  1. 基本语法

[condition] (注意 condition 前后要有空格
注意:条件非空即为true,[ banzhuan ]返回true,[]返回false

  1. 常用判断条件

(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)
  1. 案例实操
    (1)23是否大于等于22
[root@bogon datas]# [ 23 -ge 22 ]
[root@bogon datas]# echo $?
0
[root@bogon datas]#

(2)hellotest.sh是否具有写权限

[root@bogon datas]# [ -w hellotest.sh ]
[root@bogon datas]# echo $?
0
[root@bogon datas]#

(3)/opt/work/test.txt目录中的文件是否存在(0表示存在)

[root@bogon datas]# [ -e /opt/work/test.sh ]
[root@bogon datas]# echo $?
0
[root@bogon datas]# [ -e /opt/work/test.txt ]
[root@bogon datas]# echo $?
1
[root@bogon datas]# 

(4)多条件判断(&&表示前一条命令执行成功时,才执行后一条命令,||表示上一条命令执行失败后,才执行下一条命令)

[root@bogon datas]# [ condition ] && echo OK || echo NotOk
OK
[root@bogon datas]# [ condition ] && [  ] || echo NotOK
NotOK
[root@bogon datas]# 

流程控制(重点)

if判断

  1. 基本语法
if [ 条件判断式 ];then 
	程序 
fi 
#-----------或者--------------
if [ 条件判断式 ] 
	then 
		程序 
fi 

注意事项:
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
(2)if后要有空格

  1. 案例操作
    (1)输入一个数字,如果是1,则输出banzhuan zhen shaung;如果是2,则输出moyu mei jin;如果是其他,什么也不输出。
[root@bogon datas]# vim if.sh 
[root@bogon datas]# cat  if.sh 
#!/bin/bash

if [ $1 -eq 1 ];then
	echo "banzhuan zhen shuang!" 
elif [ $1 -eq 2 ];then 
	echo "moyu mei jin!" 
fi 
[root@bogon datas]# bash if.sh 1
banzhuan zhen shuang!
[root@bogon datas]# bash if.sh 2
moyu mei jin!
[root@bogon datas]# bash if.sh 0
[root@bogon datas]# 

case语句

  1. 基本语法
case $变量名 in 
	"值1")
		如果变量的值等于1,则执行程序1
		;;
	"值2")
		如果变量的值等于2,则执行程序2
		;;
	"值3")
		如果变量的值等于3,则执行程序3
		;;
	...省略其他分支...
	*)
		如果变量的值都不是以上的值,则执行此程序
		;;
esac

注意事项:
(1)case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
(2)双分号“;;”表示命令程序列结束,相当于java中的break。
(3)最后的“*)”表示默认模式,相当于java中的default

  1. 案例操作
    (1)输入一个数字,如果是1,则输出banzhuan zhen shaung;如果是2,则输出moyu mei jin;如果是其他,输出i love money。
[root@bogon datas]# vim case.sh
[root@bogon datas]# bash case.sh 1
banzhuang zhen shuang!
[root@bogon datas]# bash case.sh 2
moyu mei jin!
[root@bogon datas]# bash case.sh 3
I love money~
[root@bogon datas]# bash case.sh 5
I love money~
[root@bogon datas]# bash case.sh h
I love money~
[root@bogon datas]# bash case.sh @
I love money~
[root@bogon datas]# cat case.sh 
#!/bin/bash

case $1 in
	"1")
	echo "banzhuang zhen shuang!"
	;;
	"2")
	echo "moyu mei jin!"
	;;
	*)
	echo "I love money~"
	;;
esac
[root@bogon datas]# 

for循环

  1. 基本语法
for((初始值;循环控制条件;变量变化)) 
	do 
		程序 
	done
  1. 案例操作
    (1)从1加到100。
[root@bogon datas]# vim for.sh 
[root@bogon datas]# bash for.sh 
5050
[root@bogon datas]# cat for.sh 
#!/bin/bash
s=0
for((i=0;i<=100;i++))
do
	s=`expr $s + $i`
	#s=$[$s+$i]
done
echo $s
[root@bogon datas]# 
  1. 基本语法2
for 变量 in 值1 值2 值3...
	do 
		程序 
	done
  1. 案例实操2
    (1)打印所有输入的参数
[root@bogon datas]# vim for2.sh
[root@bogon datas]# cat for2.sh 
#!/bin/bash

for i in $*
do
	echo "banzhuan hen xin ku~ $i"
done
[root@bogon datas]# bash for2.sh 12
banzhuan hen xin ku~ 12
[root@bogon datas]# bash for2.sh 12 zhang
banzhuan hen xin ku~ 12
banzhuan hen xin ku~ zhang
[root@bogon datas]# bash for2.sh 12 zhang kusile
banzhuan hen xin ku~ 12
banzhuan hen xin ku~ zhang
banzhuan hen xin ku~ kusile
[root@bogon datas]# vim for2.sh
[root@bogon datas]# bash for2.sh 78 78
banzhuan hen xin ku~ 78
banzhuan hen xin ku~ 78
[root@bogon datas]# bash for2.sh 78 78sjdl shdlf
banzhuan hen xin ku~ 78
banzhuan hen xin ku~ 78sjdl
banzhuan hen xin ku~ shdlf
[root@bogon datas]# vim for2.sh 
[root@bogon datas]# cat for2.sh 
#!/bin/bash

for i in $*
do
	echo "banzhuan hen xin ku~ $i"
done

for j in $@
do
	echo "moyu tai shuang le! $j"
done
[root@bogon datas]# bash for2.sh 123 
banzhuan hen xin ku~ 123
moyu tai shuang le! 123
[root@bogon datas]# bash for2.sh 123 789
banzhuan hen xin ku~ 123
banzhuan hen xin ku~ 789
moyu tai shuang le! 123
moyu tai shuang le! 789
[root@bogon datas]# bash for2.sh 123 789 890
banzhuan hen xin ku~ 123
banzhuan hen xin ku~ 789
banzhuan hen xin ku~ 890
moyu tai shuang le! 123
moyu tai shuang le! 789
moyu tai shuang le! 890
[root@bogon datas]# vim for2.sh 
[root@bogon datas]# cat for2.sh 
#!/bin/bash

for i in "$*"
do
	echo "banzhuan hen xin ku~ $i"
done

for j in "$@"
do
	echo "moyu tai shuang le! $j"
done
[root@bogon datas]# bash for2.sh 123 789 890
banzhuan hen xin ku~ 123 789 890
moyu tai shuang le! 123
moyu tai shuang le! 789
moyu tai shuang le! 890
[root@bogon datas]# 

while循环

  1. 基本语法
while [ 条件判断式 ]
	do 
		程序
	done
  1. 案例操作
    (1)从1加到100
[root@bogon datas]# bash while.sh 
5050
[root@bogon datas]# cat while.sh 
#!/bin/bash

s=0
i=1
while [ $i -le 100 ]
do
	s=$[$s+$i]
	i=$[$i+1]
done
echo $s
[root@bogon datas]# 

read读取控制台输入

  1. 基本语法

read(选项)(参数)
选项:

  • -p:指定读取值时的提示符;
  • -t:指定读取值时等待的时间(秒)。

参数:

  • 变量:指定读取值的变量名
  1. 案例操作
    (1)提示7秒内,读取控制台输入的名称。
[root@bogon datas]# vim read.sh
[root@bogon datas]# cat read.sh 
#!/bin/bash

read -t 7 -p "Enter your name in 7 seconds :" NAME
echo $NAME
[root@bogon datas]# bash read.sh 
Enter your name in 7 seconds :
[root@bogon datas]# bash read.sh 
Enter your name in 7 seconds :shangshu
shangshu
[root@bogon datas]# 

函数(重点)

系统函数

  1. basename基本语法

basename [string / pathname] [suffix] (功能描述:basename命令会删掉所有的前缀包括最后一个【“/”】字符,然后将字符串显示出来。)
选项:

  • suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
  1. 案例实操
    (1)截取该/opt/work/datas/banzhuan.txt路径文件的名称
[root@bogon datas]# basename /opt/work/datas/banzhuan.txt 
banzhuan.txt
[root@bogon datas]# basename /opt/work/datas/banzhuan.txt .txt
banzhuan
[root@bogon datas]# basename banzhuan.txt 
banzhuan.txt
[root@bogon datas]# basename banzhuan.txt  .txt
banzhuan
[root@bogon datas]# basename ../datas/banzhuan.txt  .txt
banzhuan
[root@bogon datas]# 
  1. dirname基本语法

dirname文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名【非目录的部分】,然后返回剩下的路径【目录的部分】)

  1. 案例实操
    (1)获取banzhuan.txt文件的路径
[root@bogon datas]# dirname /opt/work/datas/banzhuan.txt 
/opt/work/datas
[root@bogon datas]# 

自定义函数

  1. 基本语法
[ function ] funname[()]
{
	Action;
	[return int;]
}
funname
  1. 经验技巧
    (1)必须在调用函数的地方之前,先声明函数,shell脚本是逐行运行。不会像其他语言一样先编译。
    (2)函数返回值,只能通过$?系统变量获得,可以显示加:return返回。如果不加,将以最后一条命令运行结果,作为返回值,return后跟数值n(0-255)
  2. 案例实操
    (1)计算两个输入参数的和
[root@bogon datas]# vim sum.sh
[root@bogon datas]# cat sum.sh 
#!/bin/bash

function sum()
{
	s=0;
	s=$[$1+$2]
	echo $s
}

read -p "input your paratemer1: " P1
read -p "input your paratemer2: " P2
sum $P1 $P2

[root@bogon datas]# bash sum.sh 
input your paratemer1: 1
input your paratemer2: 2
3
[root@bogon datas]# 

shell工具(重点)

cut

cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

  1. 基本用法
    cat [选项参数] filename
    说明:默认分隔符是制表符。
  2. 选项参数说明
选项参数功能
-f列号,提取第几列
-d分隔符,按照指定分隔符分隔列
  1. 案例实操
    (0)数据准备
[root@bogon datas]#  touch cut.txt
[root@bogon datas]# vim cut.txt 
[root@bogon datas]# cat cut.txt 
hong ri sheng 
zai dong fang
qi da dao man xia guang
wo he qi xing sheng 
yu ni huai 

(1)切割cut.txt第一列

[root@bogon datas]# cut  -d " " -f 1 cut.txt 
hong
zai
qi
wo
yu

(2)切割cut.txt第二、三列

[root@bogon datas]# cut -d " " -f 2,3 cut.txt 
ri sheng
dong fang
da dao
he qi
ni huai

(3)在cut.txt文件中切割出dong

[root@bogon datas]# cat cut.txt 
hong ri sheng 
zai dong fang
qi  da  dao man xia guang
wo he  qi xing sheng 
yu  ni huai 
[root@bogon datas]# cat cut.txt | grep dong
zai dong fang
[root@bogon datas]# cat cut.txt | grep dong | cut -d " " -f 2
dong
[root@bogon datas]#

(4)选取系统PATH变量值,第二个“:”开始后的所有路径:

[root@bogon datas]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@bogon datas]# echo $PATH | cut -d ":" -f 3-
/usr/sbin:/usr/bin:/root/bin
[root@bogon datas]# echo $PATH | cut -d : -f 3-
/usr/sbin:/usr/bin:/root/bin
[root@bogon datas]# echo $PATH | cut -d : -f 3
/usr/sbin
[root@bogon datas]# echo $PATH | cut -d : -f 3-
/usr/sbin:/usr/bin:/root/bin
[root@bogon datas]# echo $PATH | cut -d : -f 3-4
/usr/sbin:/usr/bin
[root@bogon datas]# echo $PATH | cut -d : -f 3-5
/usr/sbin:/usr/bin:/root/bin
[root@bogon datas]# echo $PATH | cut -d : -f 3-
/usr/sbin:/usr/bin:/root/bin
[root@bogon datas]# 

(5)切割ifconfig后打印的IP地址

[root@bogon datas]# ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.88.155  netmask 255.255.255.0  broadcast 192.168.88.255
        inet6 fe80::f74b:97b8:c76c:6c0e  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:11:73:0c  txqueuelen 1000  (Ethernet)
        RX packets 458459  bytes 636092988 (606.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 108897  bytes 8520651 (8.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 964  bytes 85438 (83.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 964  bytes 85438 (83.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@bogon datas]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.88.155  netmask 255.255.255.0  broadcast 192.168.88.255
        inet6 fe80::f74b:97b8:c76c:6c0e  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:11:73:0c  txqueuelen 1000  (Ethernet)
        RX packets 458487  bytes 636095287 (606.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 108915  bytes 8523404 (8.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@bogon datas]# ifconfig ens33 | grep "inet"
        inet 192.168.88.155  netmask 255.255.255.0  broadcast 192.168.88.255
        inet6 fe80::f74b:97b8:c76c:6c0e  prefixlen 64  scopeid 0x20<link>
[root@bogon datas]# ifconfig ens33 | grep "inet "
        inet 192.168.88.155  netmask 255.255.255.0  broadcast 192.168.88.255
[root@bogon datas]# ifconfig ens33 | grep "inet " | cut -d " " -f 2

[root@bogon datas]# ifconfig ens33 | grep "inet " | cut -d " " -f 2-
       inet 192.168.88.155  netmask 255.255.255.0  broadcast 192.168.88.255
[root@bogon datas]# ifconfig ens33 | grep "inet " | cut -d " " -f 3
    
[root@bogon datas]# ifconfig ens33 | grep "inet " | cut -d " " -f 3,4,5,6,7,8
     
[root@bogon datas]# ifconfig ens33 | grep "inet " | cut -d " " -f 8-
 inet 192.168.88.155  netmask 255.255.255.0  broadcast 192.168.88.255
[root@bogon datas]# ifconfig ens33 | grep "inet " | cut -d " " -f 8-10
 inet 192.168.88.155
[root@bogon datas]# ifconfig ens33 | grep "inet " | cut -d " " -f 10
192.168.88.155
[root@bogon datas]# 

sed

sed是一种编辑器,他一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成之后,把缓冲区的内容送往屏幕。接着处理下一行, 这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

  1. 基本语法
    sed [选项参数] 'command' filename
  2. 选项参数说明
选项参数功能
-e直接在指令列模式上进行sed的动作编辑。
  1. 命令功能描述
命令(command)功能描述
a新增,a的后面可以接字串,在下一行出现
d删除
s查找并替换
  1. 案例实操
    (0)数据准备
[root@bogon datas]# vim sed.txt
[root@bogon datas]# cat sed.txt 
shang hai
dong fang ming zhu
bei  jing
shou  du
shuang ao  zhi cheng
[root@bogon datas]#

(1)将“mei nv”这个单词插入到sed.txt第二行下,打印
注意:源文件没有改变。

[root@bogon datas]# sed '2a mei nv' sed.txt 
shang hai
dong fang ming zhu
mei nv
bei  jing
shou  du
shuang ao  zhi cheng
[root@bogon datas]# 

(2)删除sed.txt文件中所有包含ang的行
注意:源文件没有改变。

[root@bogon datas]# sed '/shang/d' sed.txt 
dong fang ming zhu
bei  jing
shou  du
shuang ao  zhi cheng
[root@bogon datas]# sed '/ang/d' sed.txt 
bei  jing
shou  du
[root@bogon datas]# cat sed.txt 
shang hai
dong fang ming zhu
bei  jing
shou  du
shuang ao  zhi cheng
[root@bogon datas]# 

(3)将sed.txt文件中ang替换成ing
注意:‘g’表示global,全部替换

[root@bogon datas]# sed 's/ang/ing/g' sed.txt 
shing hai
dong fing ming zhu
bei  jing
shou  du
shuing ao  zhi cheng
[root@bogon datas]# cat sed.txt 
shang hai
dong fang ming zhu
bei  jing
shou  du
shuang ao  zhi cheng
[root@bogon datas]# 

(4)将sed.txt文件中的第二行删除并将du替换为bei

[root@bogon datas]# sed -e '2d' -e 's/du/bei/g' sed.txt 
shang hai
bei  jing
shou  bei
shuang ao  zhi cheng
[root@bogon datas]# cat sed.txt 
shang hai
dong fang ming zhu
bei  jing
shou  du
shuang ao  zhi cheng
[root@bogon datas]# 

awk

awk一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分在进行分析处理。

  1. 基本用法
    awk [选项参数] 'pattern1{action1} pattern2{action2}...' filename
  • pattern:表示awk在数据中查找的内容,就是匹配模式。匹配正则表达式
  • action:在找到匹配内容时所执行的一系列命令。
  1. 选项参数说明
选项参数功能
-F指定输入文件折分隔符
-v赋值一个用户定义变量
  1. 案例实操
    (0)数据准备
[root@bogon datas]# cp  /etc/passwd ./
[root@bogon datas]# cat passwd 
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
saned:x:996:993:SANE scanner daemon user:/usr/share/sane:/sbin/nologin
gluster:x:995:992:GlusterFS daemons:/run/gluster:/sbin/nologin
saslauth:x:994:76:Saslauthd user:/run/saslauthd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
setroubleshoot:x:993:990::/var/lib/setroubleshoot:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
chrony:x:992:987::/var/lib/chrony:/sbin/nologin
unbound:x:991:986:Unbound DNS resolver:/etc/unbound:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
sssd:x:990:984:User for sssd:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
geoclue:x:989:983:User for geoclue:/var/lib/geoclue:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
gnome-initial-setup:x:988:982::/run/gnome-initial-setup/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
th:x:1000:1000:th:/home/th:/bin/bash
luanhao:x:1001:1001::/home/luanhao:/bin/bash
[root@bogon datas]# 

(1)搜索passwd文件以root关键字开头的所有行,并输出该行的第7列

[root@bogon datas]# awk -F: '/^root/{print $7}' passwd 
/bin/bash
[root@bogon datas]# 

(2)搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割
注意:只有匹配了pattern的行才会执行action

[root@bogon datas]# awk -F: '/^root/{print $1","$7}' passwd 
root,/bin/bash
[root@bogon datas]# 

(3)只显示/etc/passwd的第一列和第七列,以逗号分割,且在首行前面添加列名user,shell在最后一行添加“qukandahai,/bin/chuntiandaole”
注意:BEGIN在所有数据读取行之前执行;END在所有数据执行之后执行。

[root@bogon datas]# awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "qukandahai,/bin/chuntiandaole"}' 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
gluster,/sbin/nologin
saslauth,/sbin/nologin
abrt,/sbin/nologin
setroubleshoot,/sbin/nologin
rtkit,/sbin/nologin
pulse,/sbin/nologin
radvd,/sbin/nologin
chrony,/sbin/nologin
unbound,/sbin/nologin
qemu,/sbin/nologin
tss,/sbin/nologin
sssd,/sbin/nologin
usbmuxd,/sbin/nologin
geoclue,/sbin/nologin
ntp,/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
tcpdump,/sbin/nologin
th,/bin/bash
luanhao,/bin/bash
qukandahai,/bin/chuntiandaole
[root@bogon datas]# 

(4)将passwd文件中的用户id增加数值1并输出

[root@bogon datas]# 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
995
174
994
173
172
76
993
992
108
60
991
114
990
39
43
30
65535
989
75
71
90
73
1001
1002
[root@bogon datas]# cat passwd 
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
saned:x:996:993:SANE scanner daemon user:/usr/share/sane:/sbin/nologin
gluster:x:995:992:GlusterFS daemons:/run/gluster:/sbin/nologin
saslauth:x:994:76:Saslauthd user:/run/saslauthd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
setroubleshoot:x:993:990::/var/lib/setroubleshoot:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
chrony:x:992:987::/var/lib/chrony:/sbin/nologin
unbound:x:991:986:Unbound DNS resolver:/etc/unbound:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
sssd:x:990:984:User for sssd:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
geoclue:x:989:983:User for geoclue:/var/lib/geoclue:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
gnome-initial-setup:x:988:982::/run/gnome-initial-setup/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
th:x:1000:1000:th:/home/th:/bin/bash
luanhao:x:1001:1001::/home/luanhao:/bin/bash
[root@bogon datas]# 
  1. awk的内置变量
变量说明
FILENAME文件名
NR已读的记录数
NF浏览记录的域的个数(切割后,列的个数)
  1. 案例实操
    (1)统计passwd文件名,每行的行号,每行的列数
[root@bogon datas]# 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
filename:passwd, linenumber:44,columns:7
filename:passwd, linenumber:45,columns:7
[root@bogon datas]# 

(2)切割ip
注意:NF输出的是最后一列的坐标数。

[root@bogon datas]# ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.88.155  netmask 255.255.255.0  broadcast 192.168.88.255
        inet6 fe80::f74b:97b8:c76c:6c0e  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:11:73:0c  txqueuelen 1000  (Ethernet)
        RX packets 462947  bytes 636525804 (607.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 112238  bytes 8865228 (8.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1648  bytes 143738 (140.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1648  bytes 143738 (140.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@bogon datas]# ifconfig ens33 | grep "inet " | awk -F " " '{print $NF}'
192.168.88.255
[root@bogon datas]# 

(3)查询sed.txt中空行所在的行号

[root@bogon datas]# awk '/^$/{print NR}' sed.txt 
5
[root@bogon datas]# cat sed.txt 
shang hai
dong fang ming zhu
bei  jing
 1   

shou  du
shuang ao  zhi cheng
[root@bogon datas]# 

sort

sort命令是在linux里非常有用,它将文件进行排序,并将排序结果标准输出。

  1. 基本语法
    sort(选项)(参数)
选项说明
-n依照数值的大小排序
-r以相反的顺序来排序
-t设置排序时所用的分隔字符
-k指定需要排序的列

参数:指定待排序的文件列表。

  1. 案例实操
    (0)数据准备
[root@bogon ~]# vim sort.sh
[root@bogon ~]# cat sort.sh 
bb:89:5.4
aa:76:2.1
cc:67:4.9
dd:99:8.8
ee:78:7.3
ff:76:3.2

(1)按照“:”分割后的第三列倒序排序

[root@bogon ~]# sort -t : -nrk 3 sort.sh 
dd:99:8.8
ee:78:7.3
bb:89:5.4
cc:67:4.9
ff:76:3.2
aa:76:2.1
[root@bogon ~]# 

(2)按照“:”分割后的第一列正序排序

[root@bogon ~]# sort -t : -nk 1 sort.sh 
aa:76:2.1
bb:89:5.4
cc:67:4.9
dd:99:8.8
ee:78:7.3
ff:76:3.2

(3)按照“:”分割后的第一列倒序排序

[root@bogon ~]# sort -t : -nrk 1 sort.sh 
ff:76:3.2
ee:78:7.3
dd:99:8.8
cc:67:4.9
bb:89:5.4
aa:76:2.1

企业真实面试题

京东

问题1:使用Linux命令查询file1中空行所在的行号

awk '/^$/{print NR}' file1

问题2:有文件chengji.txt内容如下:

张三 40
李四 50
王五 60
使用Linux命令计算第二列的和并输出

cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'

搜狐&讯网

问题1:shell脚本里如何检查一个文件是否存在?如果不存在该如何处理?

#!/bin/bash

if [ -f file.txt ];then
	echo "文件存在!"
else
	echo "文件不存在!"
fi

新浪

问题1:用shell写一个脚本,对文本中无序的一列数字排序

#!/bin/bash
#方式1:
#cat test.txt | sort -nk 1  >> 1.txt
#方式2:
#sort -n test.txt
#方式3:排序并求和
sort -n test.txt | awk '{a+=$0;print$0} END{print "SUM="a}' 

金和网络

问题1:请用shell脚本写出查找当前文件夹(/root/work/datas/)下所有的文本文件内容中包含有字符“ang”的文件名称。

grep -r "ang" /opt/work/datas/ | cut -d " " -f 1
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值