Linux学习笔记

本文详细介绍了Linux Shell的基础知识,包括Shell的查看、安装和使用,特别是Bash的基本特性和快捷键。此外,还讲解了变量、运算、条件测试、循环结构、字符串处理和正则表达式等核心概念,是学习Linux Shell操作的全面教程。

文章目录


前言

总结了一下Shell脚本的基础知识,都结合了示例,通俗易懂。

一. Shell基础

shell是命令解释器的一个总称
在这里插入图片描述
计算机是由计算机硬件组成的,但是人类无法直接使用硬件,于是就产生了操作系统内核来控制计算机硬件,但是操作系统内核也不能被人们直接操作,例如我们所熟知的window系统和Linux系统,这些就是通过用户应用程序来控制系统内核的,众所周知计算机只能识别0和1,而命令解释器就是用来将人类自然语言转化为计算机能识别语言(0和1)的媒介,当然,不同的命令也有不同的解释器,常见的解释器有:

  1. /bin/bash (常用的)
  2. /bin/sh
  3. /bin/csh
  4. /bin/tcsh

解释器负责将用户的指令翻译为内核可以识别的指令。
通过usermod,chsh可以更改登录Shell。
下面说一下关于解释器的一些操作

1. 查看

我们可以 输入 cat /etc/shells查看我们拥有那些解释器
在这里插入图片描述

2. 安装

我们可以通过输入 yum -y install xxx安装我们想要的解释器、
在这里插入图片描述

3. 使用

我们可以通过输入 usermod -s 解释器名字 用户名 来使用这个解释器

然后输入 grep 用户名 /etc/passwd 来查看当前正在使用的解释器
在这里插入图片描述

也可以使用 chsh -s 解释器名字 用户名 将解释器修改回来
在这里插入图片描述

4. Bash基本特性

Bash的作为默认的解释器自然有他的道理,下面就来解释一下,Bash解释器的一些特别之处。

Bash解释器具有许多方便的快捷键

  1. Ctrl + a :移到命令行首
  2. Ctrl + e :移到命令行尾
  3. Ctrl + r:逆向搜索命令历史
  4. Ctrl + l:清屏
  5. Ctrl + o:执行当前命令,并选择上一条命令
  6. Ctrl + s:阻止屏幕输出
  7. Ctrl + q:允许屏幕输出
  8. Ctrl + c:终止命令,将我们当前执行的命令撤销掉
  9. Ctrl + z:挂起命令
  10. Ctrl + g:从历史搜索模式退出
  11. Ctrl + f :按字符前移(右向)
  12. Ctrl + b :按字符后移(左向)
  13. Alt + f :按单词前移(右向)
  14. Alt + b :按单词后移(左向)
  15. Ctrl + xx:在命令行首和光标之间移动
  16. Ctrl + u :从光标处删除至命令行首
  17. Ctrl + k :从光标处删除至命令行尾
  18. Ctrl + w :从光标处删除至字首
  19. Alt + d :从光标处删除至字尾
  20. Ctrl + d :删除光标处的字符
  21. Ctrl + h :删除光标前的字符
  22. Ctrl + y :粘贴至光标后
  23. Alt + c :从光标处更改为首字母大写的单词
  24. Alt + u :从光标处更改为全部大写的单词
  25. Alt + l :从光标处更改为全部小写的单词
  26. Ctrl + t :交换光标处和之前的字符
  27. Alt + t :交换光标处和之前的单词
  28. Alt + Backspace:与 Ctrl + w 相同类似
  29. 还有 Tab 快速补全代码快捷键,可以大大的减少我们的代码编辑量

查看历史命令

可用通过上下键来查看使用过的命令记录,对于一些的重复的命令我们就不必再去敲一遍了。

命令别名

有些命令具有别名 比如 ll = ls -l
也就是给一个命令又起了个名字,简写了,我们也可以自己创建别名,来提高编辑代码的速率。

标准输入输出的重定向

把输出不显示到屏幕上而显示到文件中
使用 `>` 将输出显示在文件中,同时 `>` 也意味着**覆盖**文件中以前的内容,使用 `>>` 才是在原内容上**追加**的意思

在这里插入图片描述
在这里插入图片描述
并不是所以的输出信息都可以用 >或者>>添加到文件中,以上正常的输出可以,但是错误的输出 就不行了
在这里插入图片描述
我们可以用 2>来将错误的输出添加到文件中
在这里插入图片描述
但如果又有错误又有正常输出信息呢?我们该如何把他们存放到文件中?
我们可以使用 &> 将他们一块儿存入文件中,同样的一个 > 都是覆盖,>> 是追加
在这里插入图片描述
在这里插入图片描述

管道

管道可以联合多条命令,将第一条命令的结果给第二条命令使用
比如我们来实行一下 过滤操作 ,从yum 列表中筛选出含有 bash 的软件

yum list | grep bash

在这里插入图片描述

二. hello world

我们还是先从创建第一个 hello world 开始
首先创建一个脚本:文件
shell/day1 是我提前创建好的目录
在这里插入图片描述

vim /root/shell/day1/first.sh

按s 插入Shell命令

echo  "hello world -tom"

在这里插入图片描述

按Esc 输入 :x保存并退出

然后给脚本添加可执行权限

chmod +x /root/shell/day1/first.sh

下一步 就可以执行这个脚本了

vim /root/shell/day1/first.sh

在这里插入图片描述
在上面步骤中有关键的一步 ,就是给脚本文件可执行权限 ,其实有一种方法,可以不用给权限还能运行脚本
在不具有可执行权限时,我们可以用下面方法执行脚本

  1. 解释器 脚本文件名 例如 :bash first.sh
  2. source 脚本文件名 这种方法不会启动子进程,我们可以通过 pstree(需要下载)查看进程树来观察不同。

三. 变量

1. 自定义变量

定义变量

变量名=变量值

取消变量

unset 变量名

变量规范

  1. 变量 = 两边不能加空格,不能使用关键字做变量名,如ls,cd等等。
  2. 如果变量名已经存在则覆盖以前的变量名 。
  3. 变量名称只能由字母数字下划线组成,而且不能以数字开头。
  4. 在打印一个变量的时候,最好用{}括起来
    在这里插入图片描述

2. 环境变量

变量名为大写,由操作系统维护 ,这些都是系统提前设置好的变量

  1. 存储在/etc/profile或~/.bash_profile中
  2. 命令env可以列出所有的环境变量
  3. 常见的环境变量有:PATH,PWD,USER,UID,HOME,SHELL
    PATH:命令搜索变量,负责搜索命令是否存在
    PWD:显示当前所在路径的变量
    USER:显示当前用户名
    UID:显示当前用户的ID号
    HOME:当前用户的家目录
    SHELL:显示当前正在使用的解释器
    在这里插入图片描述

3. 位置变量

bash内置变量 ,存储脚本执行时的参数
使用$n表示,n为数字序列号,如果n<10用 $n表示 ,如果n>10,用 ${n}表示
下面就来演示一下位置变量的使用方法:
先创建一个脚本文件

vim /root/shell/day1/a.sh

然后在脚本文件中设置 三个位置变量

echo $1
echo $2
echo $3

在这里插入图片描述
然后再给文件 可执行 权限

chmod +x /root/shell/day1/a.sh

最后 给位置变量赋值,再执行脚本文件

/root/shell/day1/a.sh aa bb cc

第一个位置变量 aa , 第二个位置变量 bb,第三个位置变量cc
在这里插入图片描述

4. 预定义变量

bash内置变量,可以调用,但不能赋值和修改,用来保存脚本程序的执行信息。

变量名含义
$0当前所在的进程或脚本名
$$当前运行进程的PID号
$?命令执行后的返回状态,0表示正常,1或其他值表示异常,只针对上一条命令
$#以加载的位置变量的个数
$*所有位置变量的值

下面是$?用法和其余几个的用法
在这里插入图片描述
错误显示非0,正常显示0
在这里插入图片描述
后面aa bb cc dd是4个位置变量的值

5. 单引号和双引号的区别

下面来举个例子
在这里插入图片描述
可以看出 "" 可以识别特殊符号 而 ' ' 不能识别特殊符号
其中还有 `` 反引号 与 $() 等效 ,引号和括号内都是命令, 整体得到的是命令执行的结果(a= $(),a得到的是括号内命令执行的结果)

6. 变量使用实例

read的使用

将输入的值赋给后面的变量
例如

read -p "请输入用户名:" username

在这里插入图片描述
会把提示后的输入的值赋给变量 username
但如果不给提示加双引号,会出现下面情况
在这里插入图片描述
如果我们设置输入密码

read -s -p "请输入密码:" password

前面加上-s 在我们输入时就不显示输入的内容了 安全性高点
在这里插入图片描述
read 还有一个 -t方法 ,限定在多少秒内输入 ,否者就退出输入

read -t 3 -p "请输入用户名:" username

限定用户三秒内 输入
在这里插入图片描述

局部变量和全局变量

局部变量 : 新定义的变量默认只在当前的Shell环境中生效,无法在子Shell环境中使用
全局变量 :全局变量在当前Shell和子Shell环境中均有效
设置一个局部变量

a=11

在当前的Shell中有效,但在bash中无效

下面我们设置一个全局变量

export b=22

可以看出在当前Shell中有效,在bash中也有效
在这里插入图片描述

四. Shell中基本运算

1. 整数运算

Shell 中有 + - * / %(取余)
下面演示一下
主要的执行方式 有两种

  1. $(())
  2. $[]
    在这里插入图片描述
    同时也支持一些简写表达式
简写表达式完整表达式
i++i=i+1
i- -i=i-1
i+=2i=i+2
i-=2i=i-2
i*=2i=i*2
i/=2i=i/2
i%=2i=i%2

在这里插入图片描述

2. 小数运算

Bash内建机制仅支持整数运算,不支持小数运算,我们可以通过计算机软件bc实现小数运算
bc支持交互式和非交换式两种方式计算,scale=n可以约束小数位
交互执行
在这里插入图片描述
非交互执行
在这里插入图片描述

bc也同样支持比较操作符
表达式成立返回1,不成立返回0

在这里插入图片描述

五. 条件测试

1. test测试操作

语法格式

  1. test 选项 参数
  2. [ 选项 参数 ]

基本语法:
是否为空[ -z 字符串 ]

等于 [ 字符串1 == 字符串2 ]

不等于[ 字符串1!= 字符串2 ]
在这里插入图片描述
显示 0 为正确
在这里插入图片描述
显示 非0 为不成立

2. 整数值比较

格式:[整数值1 操作符 整数值2]

操作符含义
-eq等于
-ne不等于
-ge大于或等于
-le小于或等于
-gt大于
-lt小于

应用
在这里插入图片描述
2 大于 1 ,输出 0符合
2 不大于 3, 输出 1(非0)不符合

3. 文件状态测试

操作符含义
-e判断对象是否存在,若存在则结果为真
-d判断对象是否为目录
-f判断对象是否为一般文件
-r判断对象是否有可读权限
-w判断对象是否有可写权限
-x判断对象是否有可执行权限

应用
/etc/ 为存在对象
/eeee/ 不纯在
在这里插入图片描述

4. 组合命令

我们可以使用控制符将多个命令组合
格式 : 命令1 控制符 命令2
控制符有:

  1. : 前后两个命令没有逻辑关系,先执行前面的命令,然后再执行后面的命令,无论前面的命令是否执行成功 ,都会执行后面的命令。
  2. && : 先执行前面的命令,然后再执行后面的命令,唯有前面的命令成功,才会执行后面的命令。
  3. || :先执行前面的命令,然后再执行后面的命令,当前面的命令执行成功时,便不在执行后面的命令,只有前面的命令执行不成功,才会执行后面的命令

应用
先进入 /root/shell 目录,再查看目录内容,会显示day1
在这里插入图片描述
打印 day1 表示 两条命令执行成功

我们也可利用 && 和 || 来实现多个条件的判断

[判断1] || [判断2]
[判断1] && [判断2]

5. 监控脚本基础知识

tr -s :删除多余重复的字符
例如 将 “a b c”中多余重复的空格去掉

echo "a    b    c" | tr -s " "

在这里插入图片描述
最终字母之间都只留下了一个空格

cut过滤
格式 : cut -d分割符号 -第几列 目标文件
类如 我们以 /etc/passwd 为目标文件,以 为分隔符号 ,获取第一列内容

cut -d: -f1 /etc/passwd

在这里插入图片描述
在这里插入图片描述

六. if语句

1. 单分支if语句

格式1:

if 条件
	then 命令
fi

格式2:

if 条件 ;then
	命令
fi

两种格式都可以使用 ,如果条件成立,执行命令,否者什么也不做。
下面来写一个创建用户脚本
条件为用户名和密码都不能为空,命令是创建用户并修改密码,最后的 echo 打印空 ,也就是换行。
由于 read pass 带了 -s 所以输入的密码不显示,实际是输入了密码。

read -p "请输入用户名:" user
read -s -p "请输入密码:" pass
if [ ! -z "$user" ]&&[ ! -z "$pass" ];then
         useradd "$user"
         echo "$pass" | passwd  --stdin "$user"
 fi
echo     

在这里插入图片描述
在这里插入图片描述

2. 双分支if语句

格式1:

if 条件
	then 命令1
else
	命令2
fi

格式2:

if 条件;then
	命令1
else
	命令2
fi

格式3:

if 条件1;then
	命令1
elif 条件2; then
	命令2
......
else
	命令n+1
fi

下面写一个例子:
测试主机是否能ping通

#!/bin/bash
  

if [ -z "$1" ];then
        echo -n "用法:脚本"
        echo -e "\033[32m域名或IP\033[0m"
        exit
fi
ping -c2 -i0.1 -W1 "$1" &>/dev/null
if [ $? -eq 0 ];then
        echo "$1 is up"
else
        echo "$1 is down"
fi
echo

-c2 :ping两次结束
-i0.1:ping的间隔是0.1秒
-W1 :ping的反应时间为1秒,若ping的反应时间超过1秒,默认ip ping不通

当我们什么都不输入时,会提示格式,当我们随便输入一个ip,显示ip 关闭 ,当我们输入自己的ip时显示 ip 开启

在这里插入图片描述

七. for 循环

根据变量的不同取值,重复执行命令序列
格式1:

for 变量 in 值列表
do
	命令
done

格式2:

for ((初值;条件;步长))
do
	命令
done

下面举个例子(格式1)

#!/bin/bash  

for i in 1 23 abc 2g
do
        echo "I am $i"
done

在这里插入图片描述
可以看出循环执行了5次,将in后内容遍历了一遍

格式1中的值列表有多种表示方式,也可以这样写

for i in {1..10}
for i in {a..z}
for i in {A..Z}

表示1到10,a到z,A到Z
在这里插入图片描述

下面再举个例子(格式2)

#!/bin/bash
  
for((i=1;i<=5;i++))
do
        echo "I am $i"
done

这个就不必多说了。
在这里插入图片描述

99乘法表

下面来运用for循环的格式2来写一个99乘法表

#!/bin/bash
  
for((i=i;i<=9;i++))
do      
        for((j=1;j<=i;j++))
        do      
                echo -n "$i*$j=$[i*j]"
        done    
        echo
done  

在这里插入图片描述

八. while循环

条件式循环,反复测试条件,只要成立就执行命令序列。
格式:

while 条件
do 
	命令
done

举个例子
遍历输出1-5

#!bin/bash

i=1
while [$i -le 5 ]
do
        echo $i
        let i++
done  

在这里插入图片描述

猜数字游戏

给出一个10以内的随机数让玩家猜,如果输入的数大于随机数,会显示猜大了,如果输入的数小于随机数,则显示猜小了。

#!/bin/bash
  

num=$[RANDOM%10+1]
while:
do      
        read -p "请输入1-10之间的整数:" guess
        if [$guess -eq $num ];then
                echo "恭喜你,猜对了"
                exit
        elif [ $guess -lt $num ];then
                echo "猜小了"
        else    
                echo "猜大了"
        fi      
done 

在这里插入图片描述

九. case语句

效果类似于多分支的if语句,如果与预设的值相匹配,则执行相应的操作,命令最后以 ; 结尾,如果都不匹配,则执行默认命令。
格式:

case 变量 in 
模式1)
	命令1;;
模式2)
	命令2;;
......
*)
	默认命令
esac

举一个例子
输入 tom 输出 I am tom ,输入tome 输出 I am tome ,输入其他的 则 输出 暂无此人。

#!/bin/bash
  
read -p "请输入tom 或者 tome:" key
case $key in
tom)
        echo "I am tom";;
tome)
        echo "I am tome";;
*)
        echo "暂无此人"
esac

在这里插入图片描述

石头剪刀布游戏

运用数组和case语句来创造一个石头剪刀布游戏脚本,系统会随机选择出拳的方式。

#!/bin/bash
  
gane=(石头 剪刀 布)
num=$[RANDOM%3]
computer=${game[$num]}
#通过随机数获取系统的出拳
#出拳的可能保存在一个数组中:game[0],game[1],game[2]

echo "请根据下列提示选择您的出拳方式"
echo "1.石头"
echo "2.剪刀"
echo "3.布"

read -p "请选择1-3:" person
case $person in
1)      
        if [ $num -eq 0];then
                echo "平局"
        elif [ $num -eq 1 ];then
                echo "你赢"
        else    
                echo "电脑赢"
        fi;;
2)      
        if [ $num -eq 0 ];then
                echo "电脑赢"
        elif [ $num -eq 1 ];then
                echo "平局"
        else    
                echo "你赢"
        fi;;
3)
        if [ $num -eq 0 ];then
                echo "你赢"
        elif [ $num -eq 1 ];then
                echo "电脑赢"
        else
                echo "平局"
        fi;;    
*)
        echo "必须输入1-3的数字"
esac 

在这里插入图片描述

数组

数组是一个特殊的变量,它是能够储存多个数据的集合
格式:

数组名=(数值1 数值2 数值3 ...)

下面来演示一下
创建一个名为 test 的数组
在这里插入图片描述

十. shell函数

在Shell环境中,将一些需要重复使用的操作,定义为公共的语句块,既可称为函数
格式1:

function 函数名{
	命令
	...
}

格式2:

函数名(){
	命令
	...
}

范例
不带参数的函数

imsg(){
	echo "hello world"
	echo "compute cloud"
	}

在这里插入图片描述
带参数的函数

add(){
echo $[$1+$2]
}

在这里插入图片描述
带颜色的函数
\033[:开启设置字体颜色
\033[0m : 关闭设置字体颜色

#!/bin/bash
  
cecho(){
        echo -e " \033[$1m$2\033[0m"
}
cecho 31 OK  #参数是字体的颜色
cecho 32 OK
cecho 33 OK
cecho 34 OK

在这里插入图片描述

十一. 中断和退出

脚本中的中断和退出命令
continue : 可以结束单次循环
break :可以结束循环体
exit :可以退出脚本
下面举几个例子
首先是continue ,当遍历到 3 时,跳过本次循环
在这里插入图片描述
然后是 break
当遍历到 3 时跳出循环
在这里插入图片描述
最后是 exit
如果是在脚本文件中,会退出脚本,如果在xshell中直接exit,则会退出连接。
在这里插入图片描述

十二. 字符串的处理和变量的初始化

统计变量长度

test=123456789
echo ${#test}

在这里插入图片描述

1. 字符串的截取

格式:${变量:起始位置:长度}

text=123456789

从第0位开始往后截取3位

echo ${test:0:3}

在这里插入图片描述
从第3位开始,往后截取3位

echo ${test:3:3}

在这里插入图片描述
从第四位开始,截取到最后一位

echo ${test:4}

在这里插入图片描述
从第四位开始,截取到倒数第二位

echo ${test:4:-2}

在这里插入图片描述

2. 字符串的替换

替换一个结果
格式:${变量/旧字符/新字符}
替换全部结果
格式:${变量//旧字符/新字符}

示例
在这里插入图片描述

3. 字符串的掐头去尾

掐头

字符串的掐头都是从左到右,且不会改变变量原来的值
最短匹配
格式 : ${变量#关键词}
最长匹配
格式:${变量##关键词}
举例
定义变量 test=123:456:789
分别最短匹配掐头和最长匹配掐头
*:表示 前面的所有部分
在这里插入图片描述

去尾

去尾的顺序是从右往左,同样不会改变变量原来的值
最短匹配
格式: ${变量%关键词}
最长匹配
格式:${变量%%关键词}

举例
与上面的例子差不多
因为顺序改变了,所以 * 的位置也变了一下
在这里插入图片描述

4. 变量初始化

判断一个变量是否有值,如果有值返回该变量的值,如果没有值,则返回初始值
格式:${变量:-初始值}

示例
此处给a变量赋值,b没有赋值,使用变量格式化,a返回原有的值,b返回变量初始化的值。
在这里插入图片描述

5. 随机密码

定义变量:10个数字+52个字母,用随机数对62取余数,返回的结果为[0-61],然后将其作为key的字符串位数取出字符,随机取10次,得到一个10位的随机密码。

#!/bin/bash
  
key="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
pass=""

for i in {1..10}
do
        num=$[RANDOM%${#key}]
        tmp=${key:num:1}
        pass=${pass}${tmp}
done
echo $pass
       

在这里插入图片描述

使用命令生成随机密码

  1. uuidgen:生成随机序列号
  2. openssl: 生成可控长度的随机序列号,例子后面的15不是指的序列号的长度,而是一个控制值,值越大,序列号越长。
    在这里插入图片描述

使用随机设备文件生成随机密码

/dev/random : 能够一直产生随机码,不会自动终止,效率很慢,大概十几秒出一次。
在这里插入图片描述
/dev/urandom: 这个文件也能源源不断的产生随机码,而且效率很高。
在这里插入图片描述

十三. 正则表达式

描述一个字符集合的表达方式,根据特征模糊的匹配内容。

1. 基本正则符号

正则符号描述
abc匹配abc
^匹配开头
$匹配结尾
[集合]匹配集合中的任意单个字符
[ ^ 集合]对集合取反
.匹配任意单个字符
*匹配前一个字符任意次(包含0次)
.*匹配任意
{n,m}匹配前一个字符n到m次
{n,}匹配前一个字符至少n次
{n}匹配前一个字符n次

2. 扩展正则符号

正则符号描述
+匹配前面的字符至少一次
匹配前面的字符0或一次
()组合与保留
|或者
{n,m}匹配前面的字符n到m次
{n,}匹配前面的字符至少n次
{n}匹配前面的字符n次

3. Perl兼容的正则符号

正则符号描述
\b匹配单词边界
\w匹配字符数字下划线
\W和\w相反
\s匹配空白
\d匹配数字
\d+匹配多个数字
\D匹配非数字

4. grep语法

grep语法支持正则表达式,下面介绍一下grep语法,以及一些正则表达式的练习示例。
格式: grep [选项] 匹配模式 [文件]...
常用的选项:
-i:忽略大小写
-v:取反匹配(全部)
-w:匹配单词
-q:静默匹配,不将结果显示在屏幕上

下面来介绍一些练习的指令
创建一个名为 test.txt 的文件,并在里面写上足够的内容

  1. 过滤文件中 带 the 的行
grep the test.txt

在这里插入图片描述

  1. 过滤文件中带 the 的行,不区分大小写
grep -i the test.txt

在这里插入图片描述

  1. 过滤包含数字的行
grep "[0-9]" test.txt
grep -P "\d" test.txt

在这里插入图片描述

  1. 过滤包含 in和the 的行
grep -E "(in|the)" test.txt

在这里插入图片描述

  1. 过滤包含两个 o 的行
grep "o\{2\}" test.txt
  1. 过滤以大写字母开头的行
grep "^[A-Z]" test.txt
  1. 过滤 ou 前面不是th的行
grep -E "[^(th)]ou" test.txt
  1. 过滤不以 . 结尾的行
grep "[^.]$" test.txt
  1. 过滤以 .结尾的行
grep "\.$" test.txt
  1. 过滤空白行
grep "^$" test.txt
  1. 过滤以数字开始的行
grep "^[0-9]" test.txt
  1. 过滤所有的字母
grep "[a-zA-Z]" test.txt
  1. 过滤所有符号
grep -P "\W" test.txt

十四. sed基础

Stream Editor,流式编辑器,非交互式,对文档的处理是逐行处理,可以对文本进行增删改查等操作。
语法格式:

sed [选项] '[定位符]指令' 文件名
命令 | sed [选项] '[定位符]指令'

常用命令选项 :

  • -n:屏蔽默认输出
  • -i:直接修改源文件
  • -r:支持扩展正则

常用的sed指令:

  • p (print): 打印行
  • d (delete) :删除行.
  • c (replace) :替换行
  • s (substitution) :替换关键词
  • i (insert):插入
  • a (append) :追加
  • r (read):读取文件|导入文件内容
  • w (write) :文件另存为导出文件内容
  • = : 打印行号

1. 打印文件内容

示例
-n : 默认屏蔽输出,控制只打印所需内容,若不加,则会把所有内容都打印出来。
‘3p’ : 3表示第三列,p表示打印 。
打印文件指定内容

 sed -n '3p' /etc/passwd

在这里插入图片描述
从第一行打印到第三行

sed -n '1,3p' /etc/passwd 	

在这里插入图片描述
从第二行开始,步长为2,也就是打印2 4 6 8 …偶数行

sed -n '2~2p' /etc/passwd 

打印第2行以及后面的3行

sed -n '2,+3p' /etc/passwd 

打印1,3,6行内容

sed -n '1p;3p;6p' /etc/passwd 

打印除2以外的所有行

sed -n '2!p' /etc/passwd 

打印包含 root 的行

sed -n '/root/p' /etc/passwd 

2. 正则定位

从文件中过滤包含3个数字的行,运用正则表达式定位

sed -rn '/[0-9]{3}/p' /etc/passwd

在这里插入图片描述

3. 删除文件内容

删除文件内所有内容(谨慎使用)
不加 -i 对源文件不会有影响

sed -i 'd' /etc/hosts

删除1-3行

sed -i '1,3d' /etc/hosts

删除所有不包含dev的行

sed -i '/dev/!d' /etc/hosts

删除所有以 # 开头的行

sed -i '/^#/d' /etc/hosts

删除所有空白行

sed -i '/^$/d' /etc/hosts

4. 替换文件内容

不使用 -i,源文件不会被改变

将所有的行替换为123456

sed -i 'c 123456' /etc/hosts

将第3行改为12345

sed -i '3c 123456' /etc/hosts

通过观察可以看出,格式都大同小异,只是命令和sed指令改变了而已

5. 替换文件内关键词

不加 -i 对源文件不会有影响

将每一行的第1个123都替换成xxx

sed -i 's/123/xxx/' /etc/hosts

将每一行的第2个123都替换成xxx

sed -i 's/123/xxx/2' /etc/hosts

将所有的123都替换成xxx

sed -i 's/123/xxx/g' /etc/hosts

将第2行的123都替换成xxx

sed -i '2s/123/xxx/g' /etc/hosts

将第2行的123都替换成空(也就是删掉)

sed -i '2s/123//g' /etc/hosts

6. 文件中插入内容

不加 -i 对源文件不会有影响

在第二行前插入 123

sed -i '2i 123' /etc/hosts

在含有abc那一行的前面插入123

sed -i '/abc/i 123' /etc/hosts

在第二行后追加 123

sed -i '2a 123' /etc/hosts

在含有abc那一行的后面追加123

sed -i '/abc/a 123' /etc/hosts

7. 文件导入内容

不加 -i 对源文件不会有影响

在 test.txt 文件内容的第2行后面插入 /etc/hosts 文件内容

sed -i '2r /etc/hosts' test.txt

在 test.txt 文件内容的 含有abc的 那一行 后面插入 /etc/hosts 文件内容

sed -i '/abc/r /etc/hosts' test.txt

8. 文件内容导出

将指定文件内容导出,存到另一个文件中去,如果目标文件不存在,系统会自动创建。
不加 -i 对源文件不会有影响
将 test.txt 文件的内容导出另存到 copy_test.txt 文件中去

sed  -i 'w copy_test.txt' test.txt

将test.txt文件的2-4行 另存到文件line.txt中

sed  -i '2,3w line.txt' test.txt

将test.txt文件的所有包含abc的行 另存到文件abc.txt中

sed  -i '/abc/w abc.txt' test.txt

十五. awk基础

数据处理引擎,基于模式匹配检查输入文本,逐行处理并输出,通常用在Shell脚本中,获取指定的数据,单独用时,可对文本数据做统计。

格式1:前置命令 | awk [选项] ‘[条件]{指令}’
格式2:awk [选项] ‘[条件]{指令}’ 文件...
补充:

  1. 指令可以是多条语句,但语句之间要用 隔开
  2. 条件如果不写的话,默认全部逐行处理。

awk的内置变量

内置变量含义
FS保存或设置字段分隔符,例如FS= “:”,与-F功能一样
$n指定分隔的第n个字段,如$1、$3分别表示第1、第3列
$0当前读入的整行文本内容
NF记录当前处理行的字段个数(列数)
NR记录当前已读入行的数量(行数)

示例:
先创建一个文件 test1.txt 有以下内容
在这里插入图片描述
以空格为分割符,逐行打印文件内容的第1列和第3列

awk '{print $1,$3}' test1.txt

在这里插入图片描述
把文件中的空格改为:,以 为分隔符打印第2列

awk -F: '{print $2}' test1.txt

在这里插入图片描述
打印文件当前处理的行,和本行有几列

awk -F: '{print NR,NF}' /etc/passwd

在这里插入图片描述

打印常量用户名和UID

awk -F: '{print "用户名:"$1,"UID:"$3}' /etc/passwd

在这里插入图片描述

1. awk过滤的时机

  • BEGIN{} :在所有行前处理,读入第一行文本之前执行,一般用来初始化操作。
  • {} : 逐行处理,逐行读入文本执行相应的处理,最常见的编译指令块。
  • END{} : 在所有行后处理,处理完最后一行文本后执行,一般用来输出处理结果。

示例
开始结束执行文件时打印行数

awk -F: 'BEGIN{print NR} END{print NR}' /etc/passwd

在这里插入图片描述
统计有多少行含有bash,在开始设置变量x,逐行读取,满足条件x加1,最后打印出x的值
在这里插入图片描述

2. awk条件判断

格式 :awk [选项] ‘[条件]{指令}’ 文件...

举例
打印带root的行

awk -F: '/root/{print}' /etc/passwd

在这里插入图片描述
打印一切不是bash结尾的行

awk -F: '$71~/bash$/{print}' /etc/passwd

打印第二行内容

awk -F 'NR==2' /etc/passwd

将文件内容任意一行第三列的值大于等于0小于2的值打印出来

awk -F: '$3>=0&&$3<2{print$1,$3}' /etc/passwd

在这里插入图片描述
将第三列等于1或者等于7的内容打印出来

awk -F: '$3==1||$3==7{print$1,$3}' /etc/passwd

3. awk流程控制

单分支if判断

格式: awk '{指令}' 文件

示例
如果 第三列大于等于1000 那么i+1,最后输出i的值

awk -F: '{if($3>=1000){i++}} END{print i}' /etc/passwd

将 uptime中cpu的负载管道给awk,如果最后一列负载大于0.01则输出负载

uptime|awk '{if($NF>0.01){print "CPUload:"$NF}}'

双分支if判断

举例

第三列大于等于1000的为普通用户,小于1000的为系统用户,统计普通用户和系统用户的个数

 awk -F: '{if($3>=1000){i++}else{j++}}END{print "普通用户:"i,"系统用户:"j}' /etc/passwd

在这里插入图片描述

多分支if判断

举例
设定 以-开头的是普通文件,以d开头的是目录,判断各种的个数

ls -l /etc | awk '{if($1~/^-/){x++} else if($1~/^d/){y++} else{z++}}END{print "普通文件个数:"x,"目录个数:"y,"其他个数:"z}'

在这里插入图片描述

4. awk的for循环

awk的for循环采用的和c语言一样的语法格式

for(表达式1;表达式2;表达式3){指令}

举例

awk 'BEGIN{ for(i=1;i<5;i++){print i}}'

在这里插入图片描述

5. awk数组

定义:数组名[下标]=元素值
调用:数组名[下标]
遍历:for(变量名 in 数组名){print 数组名[变量]}
示例
定义与调用

 awk 'BEGIN{name[0]="jim";name[1]="tom";print name[1],name[0]}'

在这里插入图片描述
其数组下标也不一定要为数字,也可以为字符串

 awk 'BEGIN{age["tom"]=22;age["jim"]=18;print age["tom"],age["jim"]}'

在这里插入图片描述
遍历的使用

 awk 'BEGIN{ x[0]=0;x[1]=1;x[2]=2;x[3]=3;for(i in x){print x[i]}}'

在这里插入图片描述

十六. 综合实例

1. 循环嵌套

打印星星矩阵

连续打印5组每行有5列的星星


#!/bin/bash
for i in {1..5}
do
        echo -n "*"
done
echo
echo

for i in {1..5}
do
        for j in {1..5}
        do
                echo -n "*"
        done
        echo
done

在这里插入图片描述

排列和组合

打印所有1-3的组合方式

#!/bin/bash
  
for i in {1..3}
do
        for j in {1..3}
        do
                echo "${i}${j}"
        done
done

在这里插入图片描述

打印梯形

#!/bin/bash
  

for ((i=1;i<=6;i++))
do
        for((j=1;j<=i;j++))
        do
                echo -ne "\033[101m \033[0m"
        done
        echo
done


在这里插入图片描述

打印对称梯形

for ((i=1;i<=6;i++))
do
        for((j=1;j<=i;j++))
        do
                echo -ne "\033[101m \033[0m"
        done
        echo
done


for ((i=1;i<=5;i++))
do
        for((j=5;j>=i;j--))
        do
                echo -ne "\033[101m \033[0m"
        done
        echo
done
  

在这里插入图片描述

2. 带菜单的脚本


#!/bin/bash
  
echo "1.查看剩余内存容量"
echo "2.查看根分区剩余容量"
echo "查看CPU十五分钟负载"
echo "4.查看系统进程数量"
echo "5.查看系统账户数量"
echo "6.退出"

while :
do
        read -p "请输入选项[1-6]:" key
        case $key in
1)
        free | awk '/Mem/{print $NF}';;
2)
        df | awk '/\/$/{print $4}';;
3)
        uptime | awk '{print $NF}';;
4)
        ps aux | wc -l;;
5)
        sed -n '$=' /etc/passwd;;
6)
        exit
esac
done

在这里插入图片描述

3. 备份数据

date=$(date +%Y%m%d)
if [ ! -f /tmp/log-$date.tar.gz ];then
        tar -czf /tmp/log-$date.tar.gz /var/log
fi

在这里插入图片描述

4. 安全脚本

HASH值: HASH值与文件名称,时间,大小等信息无关,仅与内容有关
如果文件内容没有发生改变,HASH不变,否者改变。我们可以用MD5,SHA256,SHA512来计算哈希值。
主要用来校对文件拷贝后是否发生错误导致拷贝文件变化。
计算某一文件的HASH值
当某一文件被恶意篡改时,我们不用逐个打开文件比较内容,而直接可以比较哈希值,来确定被修改文件。

md5sum /etc/passwd

在这里插入图片描述
举例
将etc目录下所有文件的哈希值存入data.log文件中

#!/bin/bash

for i in $(ls /etc/*.conf)
do      
        md5sum $1 >> /tmp/data.log
done 

在这里插入图片描述

5. 格式化输出passwd

awk -F: 'BEGIN{print"用户名 UID 家目录"} {print $1,$3,$6}' /etc/passwd | column -t

在这里插入图片描述
从/etc/passwd中将所有能登陆的账户名提取出来,并从/etc/shadow中提取账户对应的密码

#!/bin/bash
  

USER=$(awk -F: '/bash$/{print $1}' /etc/passwd)
for i in $USER
do

        awk -F: -v iuser=$i '$1==iuser {print $1,$2}' /etc/shadow
done

在这里插入图片描述

创作不易,给个三连鼓励一下吧😜

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤米先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值