Linux云计算 |【第二阶段】SHELL-DAY4

主要内容:

grep、egrep的使用,基本/扩展正则、sed的使用(非交互、逐行处理、常用命令与选项)

补充:grep [-E]选项,表示允许使用扩展的正则表达式(同等于egrep)

一、grep 与 egrep 的使用

grep 和 egrep 是 Unix 和 Linux 系统中用于文本搜索的强大工具。它们可以根据指定的模式(正则表达式)在文件中查找匹配的行。虽然 egrep 是 grep 的一个变种,但在现代系统中,grep 已经集成了 egrep 的功能,因此通常推荐使用 grep 并指定选项来实现相同的效果。

1、grep 基本用法

  • 格式:grep [选项] 模式 [文件...]
  • 常用选项:

-i:忽略大小写。
-v:反向匹配,显示不匹配的行。
-r:递归搜索目录下的所有文件。
-n:显示匹配行的行号。
-E:使用扩展正则表达式(等同于 egrep)。
-o:只显示匹配的部分,而不是整行。

示例:

基本搜索:

grep "pattern" file.txt

忽略大小写:

grep -i "pattern" file.txt

反向匹配:

grep -v "pattern" file.txt

递归搜索:

grep -r "pattern" /path/to/directory

显示行号:

grep -n "pattern" file.txt

使用扩展正则表达式:

grep -E "pattern" file.txt

2、egrep 基本用法

egrep 是 grep -E 的别名,用于支持扩展正则表达式。在现代系统中,grep 已经集成了 egrep 的功能,因此通常推荐使用 grep -E。

文本处理顺序:以行为单位,逐行进行处理,默认只输出与表达式相匹配的文本行

  • 格式1:egrep [选项] ‘正则表达式’ 文件...
  • 格式2:前置命令 | egrep [选项] ‘正则表达式’
  • 常用选项:

[-i]  忽略字母大小写

[-v]  条件取反

[-c]  统计匹配的行数      //与wc -l 效果相同

[-q]  静默、无任何输出,一般用于检测(通过$?返回值,0为有匹配。非0为无匹配)

[-n]  显示出匹配结果所在的行号

[--color]  标号显示匹配字串

示例:

基本搜索:

egrep "pattern" file.txt

忽略大小写:

egrep -i "pattern" file.txt

反向匹配:

egrep -v "pattern" file.txt

递归搜索:

egrep -r "pattern" /path/to/directory

显示行号:

egrep -n "pattern" file.txt

案例:典型的应用场合

扩展正则表达式支持更多的元字符和功能,例如 +、?、| 等。

  1. 匹配一个或多个字符

    grep -E "a+" file.txt
    
  2. 匹配零个或一个字符

    grep -E "a?" file.txt
    
  3. 匹配多个模式之一

    grep -E "pattern1|pattern2" file.txt

grep 命令不带-E选项时,支持基本正则匹配模式。比如“word”关键词检索、“^word”匹配以word开头的行、“word$”匹配以word结尾的行等。

例如:输出以“r”开头的用户记录

[root@svr5 ~]# grep '^r' /etc/passwd
root:x:0:0:root:/root:/bin/bash
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin

例如:输出以“localhost”结尾的行

[root@svr5 ~]# grep 'localhost$' /etc/hosts
127.0.0.1               localhost.localdomain localhost

若使用grep -E或egrep命令,可支持扩展正则匹配模式,能够自动识别 |、{} 等扩展正则表达式中的特殊字符;

[root@svr5 ~]# grep -E '^(root|daemon)' /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
同等于
[root@svr5 ~]# egrep '^(root|daemon)' /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin

二、正则表达式概述

正则表达式(Regular Expression,简称 regex 或 regexp)是一种用于匹配字符串中字符模式的强大工具。它广泛应用于文本搜索、替换、验证和提取等操作。正则表达式由普通字符(如字母、数字)和元字符(具有特殊意义的字符)组成,通过这些字符的组合可以描述复杂的字符串模式。

1.基本正则表达式(Basic Regular Expressions,BRE)

基本正则表达式使用较少的元字符,通常需要反斜杠 \ 进行转义。(可直接使用grep)

正则符号

含义

示例

说明

^

匹配行首

^abc

以abc开头的行

^#

以#号开头的行(比如注释行)

$

匹配行尾

abc$

以abc结尾的行

^$

空行

[]

集合,匹配除换行符外的任意单个字符

[abc]

例如 a、b 或 c

[^]

匹配不在方括号内的任意一个字符

[^abc]

.

匹配除换行符外的任意单个字符a.c匹配 abc、a1c、aAc 等

*

匹配前一个字符任意次数

注意:*不允许单独使用

a*

匹配 a、aa、aaa 等。

(abc)*

0个或多个连续的abc

.*

任意长度的任意字符串,包括空行

\{n\}

匹配前面的字符恰好 n 次

(ab)\{3\}

匹配ababab

\{n,m\}

匹配前面的字符至少 n 次,但不超过 m 次

(ab)\{1,3\}

匹配ab、abab、ababab

\{n,\}

匹配前面的字符至少 n 次

(ab)\{2,\}

匹配2个及以上连续的ab

\(\)

保留、组合为整体

ab{1,3}

匹配ab、abb、abbb

\(ab\){1,3}

匹配ab、abab、ababab

2.扩展正则表达式(Extended Regular Expressions,ERE)

(需要使用egrep或grep -E)

正则符号

含义

示例

说明

+

最少匹配一次

a+

一个或多个连续的a

(abc)+

一个或多个连续的abc

最多匹配一次

a?

0个或1个a

(abc)?

0个或1个abc

{n,m}

匹配前一个字符n到m次

(ab){1,3}

匹配ab、abab、ababab

()

组合为整体

ab{1,3}

匹配ab、abb、abbb

(ab){1,3}

匹配ab、abab、ababab

|

或者

root|bin

匹配root、bin

\b

单词边界

\broot\b

匹配单词root、不匹配keroot、rooty、brooty等字符串

3.匹配指定字符集合内的任何一个字符,[ ]内加【^】可取反

示例

说明

[abcd_?]

匹配a、b、c、d、_、?

[a-z]

匹配任意小写字母

[A-Z]

匹配任意大写字母

[0-9]

匹配任意数字

[a-Z]

匹配任意字母

[a-Z0-9]

匹配任意字母或数字

[^A-Z]

匹配包括非大写字母的行

^[^a-z]

匹配不以小写字母开头的行

4.整体及边界匹配

正则符号

含义

示例

说明

()

组合为整体

ab{1,3}

匹配ab、abb、abbb

(ab){1,3}

匹配ab、abab、ababab

|

或者

root|bin

匹配root、bin

\b

单词边界

\broot\b

匹配单词root、不匹配keroot、rooty、brooty等字符串

\

单词的开头

\

匹配以th开头的单词

\>

单词的结束

\

作用与\broot\b相同

\w

字母数字下划线

\wa

匹配xa,不匹配#a

\s

匹配空白

\sa

匹配 a,不匹配xa

\d

匹配数字

-P\da

匹配5a,不匹配xa


练习1:基本正则【^】、【$】、【[]】、【[^]】

[root@svr7 opt]# head -5 /etc/passwd > user     //准备练习素材
[root@svr7 ~]# cat user
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

例如:过滤以root开头的行

[root@svr7 opt]# grep ‘^root’ user
root:x:0:0:root:/root:/bin/bash

例如:过滤以bash结尾的行

[root@svr7 opt]# grep 'bash$' user
root:x:0:0:root:/root:/bin/bash

例如:过滤空行

[root@svr7 opt]# grep '^$' user

例如:过滤包含‘root’的行

[root@svr7 opt]# grep 'root' user 
root:x:0:0:root:/root:/bin/bash

例如:匹配集合中任意单个字符(即r o o t)

[root@svr7 opt]# grep '[root]' user
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
结果同上
[root@svr7 opt]# grep '[rot]' user    //匹配集合中任意单个字符(即r o t)

例如:匹配含任意小写字母的行

[root@svr7 opt]# grep '[a-z]' user

例如:匹配含任意大写字母的行

[root@svr7 opt]# grep '[A-Z]' user

例如:匹配含任意字母的行

[root@svr7 opt]# grep '[a-Z]' user

例如:匹配含任意数字的行

[root@svr7 opt]# grep '[0-9]' user

例如:匹配除数字的行,[]集合中的【^】代表取反

[root@svr7 opt]# grep '[^0-9]' user

例如:匹配除字母数字的行,可匹配特殊符号

[root@svr7 opt]# grep '[^a-Z0-9]' user

例如:匹配含字母数字的行

[root@svr7 opt]# grep '[a-Z0-9]' user

练习2:基本正则【.】、【*】

例如:匹配r与t之间有2个任意字符的行

[root@svr7 opt]# grep 'r..t' user
root:x:0:0:root:/root:/bin/bash

例如:匹配r与t之间有3个任意字符的行,无则不输出

[root@svr7 opt]# grep 'r...t' user

注意:错误用法,注意:【*】不允许单独使用,非通配符

例如:grep '*' user

例如:匹配*前一个字符o任意次数(0次数)都行

[root@svr7 opt]# grep 'ro*t' user
root:x:0:0:root:/root:/bin/b-ash

例如:匹配任意单个字符,文档中每个字符都为任意字符

[root@svr7 opt]# grep '.' user
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

注意:单个字符匹配,除换行符(\n)以外的每个字符,都为任意单个字符

例如:【.*】的组合在正则中,相当于通配符*的效果

[root@svr7 opt]# grep '.*' user
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

注意:匹配任意字符,包括空行

例如:输出“r”开头且以“sh“结尾的用户记录,即中间可以是任意字符

[root@svr7 opt]# grep 'r.*sh' user
root:x:0:0:root:/root:/bin/bash

练习3:基本正则【\{n\}】、【\{n,m\}】、【\{n,\}】、【\(\)】

例如:匹配前一个字符o可以有2个的行

[root@svr7 opt]# grep 'ro\{2\}t' user
root:x:0:0:root:/root:/bin/bash

例如:匹配前一个字符o可以有3个的行

[root@svr7 opt]# grep 'ro\{3\}t' user

例如:匹配前一个字符o可以有1~2个的行

[root@svr7 opt]# grep 'ro\{1,2\}t' user 
root:x:0:0:root:/root:/bin/bash

例如:匹配前一个字符o可以有2~4个的行

[root@svr7 opt]# grep 'ro\{2,4\}t' user
root:x:0:0:root:/root:/bin/bash

例如:匹配前一个字符o可以有4~6个的行

[root@svr7 opt]# grep 'ro\{4,6\}t' user

例如:匹配前一个字符o可以有1个以上的行

[root@svr7 opt]# grep 'ro\{1,\}t' user
root:x:0:0:root:/root:/bin/bash

例如:匹配前一个字符o可以有3个以上的行

[root@svr7 opt]# grep 'ro\{3,\}t' user

例如:匹配前一个字符连续2个”0:”的行

[root@svr7 opt]# grep '\(0:\)\{2\}' user
root:x:0:0:root:/root:/bin/bash

补充:()小括号的作用是将字符组合为一个整体

练习4:基本/扩展正则【\{n\}】、【\{n,m\}】、【\{n,\}】、【\(\)】

例如:匹配前一个字符o可以有1个以上的行

[root@svr7 opt]# grep 'ro{1,}t' user     //grep不支持扩展正则
[root@svr7 opt]# echo $?
1

注意:grep支持基本正则,不支持扩展正则,使用-E选项支持扩展正则且可去掉所有【\】

改成扩展正则的用法:

[root@svr7 opt]# grep -E 'ro{1,}t' user
root:x:0:0:root:/root:/bin/bash
[root@svr7 opt]# egrep 'ro{1,}t' user
root:x:0:0:root:/root:/bin/bash

补充:统计使用bash作登录Shell的用户数量

[root@svr7 opt]# egrep -c '/bin/bash$' /etc/passwd  
7

练习5:扩展正则【{n}】、【{n,m}】、【{n,}】、【()】、【+】、【?】、【|】、【\b】

例如:匹配前一个字符o可以有2个以上的行

[root@svr7 opt]# egrep 'ro{2}t' user
root:x:0:0:root:/root:/bin/bash

例如:匹配前一个字符o可以有1到2的行

[root@svr7 opt]# egrep 'ro{1,2}t' user
root:x:0:0:root:/root:/bin/bash

例如:匹配前一个字符o可以有2个以上的行

[root@svr7 opt]# egrep 'ro{2,}t' user
root:x:0:0:root:/root:/bin/bash

例如:匹配前一个字符连续2个”0:”的行

[root@svr7 opt]# egrep '(0:){2,}' user
root:x:0:0:root:/root:/bin/bash

例如:最少匹配字符o一次

[root@svr7 opt]# egrep 'ro+t' user
root:x:0:0:root:/root:/bin/bash
[root@svr7 opt]# egrep 'roo+t' user   //结果同上

例如:最多匹配字符o一次

[root@svr7 opt]# egrep 'roo?t' user
root:x:0:0:root:/root:/bin/bash

例如:匹配root、bin的行

[root@svr7 opt]# egrep 'root|bin' user
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

例如:匹配以root开头、bin开头的行

[root@svr7 opt]# egrep '^root|^bin' user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@svr7 opt]# cat abc.txt   //准备测试文件
the
there
th
_th_
[root@svr7 opt]# egrep ‘the\b’ abc.txt   //匹配单词the,后面不能有数字、字母、下划线
the
[root@svr7 opt]# egrep ‘the\>’ abc.txt    //结果同上[root@svr7 opt]# egrep ‘\bth\b’ abc.txt  //匹配单词th,前后面都不能有数字、字母、下划线
th
[root@svr7 opt]# egrep ‘\<bth\>’ abc.txt   //结果同上

三、sed基本用法

sed(stream editor)是一个强大的文本处理工具,主要用于对文本进行查找、替换、删除、插入等操作。它广泛应用于脚本、自动化任务和文本处理中。以下是 sed 的基本用法和常用命令。

功能:非交互式,基于模式匹配过滤及修改文本,逐行处理并将结果输出到屏幕,可实现对文本的输出、删除、替换、复制、剪切、导入、导出等各种操作;

1、sed命令格式解析

格式:sed [选项] '[定址符]命令' 文件

常见选项:

  • -n:静默模式,不自动打印模式空间的内容
  • -e:执行多个命令
  • -f:从文件中读取命令
  • -i:直接修改文件内容
  • -r:使用扩展正则表达式(ERE)

补充:条件(定址符),可以是行号或者/正则表达式/:

定址符(执行指令的条件)控制sed需要处理文本的范围;不加则逐行处理所有行

  • ① 行号可以使用单个数字表示单行;或者3,5表示连续的多行;省略条件(定址符),则默认逐行处理全部文本;
  • ② 匹配正则时,需要使用【/正则表达式/】;

常用动作命令:

相关说明如下:

  • ① 条件可以是行号或者/正则表达式/;(没有条件时,默认为所有条件)
  • ② 指令可以是增、删、改、查等指令;
  • ③ 默认sed会将所有输出的内容都打印出来,可以使用[-n]屏蔽默认输出;
  • ④ 选项中可以使用[-r]选项,让sed支持扩展正则,不加[-r]不支持扩展正则;

多个指令可以使用分号【;】隔离(用分号来隔离多个操作)

 示例:

1)替换(s)

替换命令是 sed 中最常用的命令之一,用于将匹配到的字符串替换为新的字符串。

格式:sed 's/旧字符串/新字符串/' 文件

sed 's/foo/bar/' example.txt    # 将 example.txt 文件中的第一个 foo 替换为 bar。

2)全局替换

默认情况下,sed 只替换每行中第一个匹配到的字符串。要进行全局替换,可使用 g 标志。

格式:sed 's/旧字符串/新字符串/g' 文件

sed 's/foo/bar/g' example.txt   # 这个命令将 example.txt 文件中的所有 foo 替换为 bar。

3)删除(d)

删除命令用于删除匹配到的行。

格式:sed '/匹配模式/d' 文件

sed '/foo/d' example.txt     # 这个命令删除 example.txt 文件中包含 foo 的所有行。

 4)插入(i)和追加(a)

插入和追加命令用于在匹配到的行之前或之后插入新行。

格式:sed '/匹配模式/i 新行' 文件

格式:sed '/匹配模式/a 新行' 文件

sed '/foo/i bar' example.txt    # 将包含 foo 的行之前插入 bar
sed '/foo/a bar' example.txt    # 将包含 foo 的行之后插入 bar

5)打印(p)

打印命令用于打印匹配到的行。

格式:sed -n '/匹配模式/p' 文件

sed -n '/foo/p' example.txt   # 这个命令打印 example.txt 文件中包含 foo 的所有行。

 6)多个命令

可以使用 -e 选项或分号(;)来执行多个命令。

格式:sed -e '命令1' -e '命令2' 文件
格式:sed '命令1; 命令2' 文件

sed -e 's/foo/bar/' -e '/baz/d' example.txt
sed 's/foo/bar/; /baz/d' example.txt# 这两个命令分别将 foo 替换为 bar 并删除包含 baz 的行

练习:准备测试文件

[root@svr7 opt]# cat -n user
1  root:x:0:0:root:/root:/bin/bash
2  bin:x:1:1:bin:/bin:/sbin/nologin
3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
4  adm:x:3:4:adm:/var/adm:/sbin/nologin
5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

① sed命令的【 -n】 选项

例如:执行p打印等过滤操作时,希望看到的是符合条件的文本。但不使用任何选项时,默认会将原始文本一并输出,从而干扰过滤效果;

[root@svr7 opt]# sed 'p' user    //不使用[-n],则不屏蔽默认输出;
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
...

可以发现所有的行都被显示出来了(第1行重复2次),正确的用法应该添加 -n 选项,这样就可以只显示第1行

[root@svr7 opt]# sed -n 'p' user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
...

② sed命令的【 -i】 选项

例如:正常情况下sed命令所做的处理只是把操作结果(包括打印、删除等)输出到当前终端屏幕,而并不会对原始文件做任何更改

[root@svr7 opt]# sed 'd' user  //删除所有行
[root@svr7 opt]# cat user   //查看原始文本,并未改动
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
...

若希望直接修改文件内容,应添加选项 -i

[root@svr7 opt]# sed -i '1,4d' user
[root@svr7 opt]# cat user
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

③ 多个指令可以使用分号隔离

例如:用分号来隔离多个操作

[root@svr7 opt]# sed -n '1p;4p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin

 


示例:选项-n屏蔽默认输出,-r扩展正则;指令p打印行、$=行数、=行号、!取反、1~2p奇数行、2~2p偶数行
[root@svr7 opt]# cat -n user    //测试文件
1  root:x:0:0:root:/root:/bin/bash
2  bin:x:1:1:bin:/bin:/sbin/nologin
3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
4  adm:x:3:4:adm:/var/adm:/sbin/nologin
5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

例如:逐行打印所有行(-n屏蔽默认输出;p打印行)

[root@svr7 opt]# sed -n 'p' user

例如:输出第1行

[root@svr7 opt]# sed -n '1p' user
root:x:0:0:root:/root:/bin/bash

例如:输出第2行

[root@svr7 opt]# sed -n '2p' user
bin:x:1:1:bin:/bin:/sbin/nologin

例如:输出第1~3行

[root@svr7 opt]# sed -n '1,3p' user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

例如:输出第2以及后面1行

[root@svr7 opt]# sed -n '2,+1p' user
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

例如:输出第2行,第4行

[root@svr7 opt]# sed -n '2p;4p' user
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

例如:在sed中使用正则表达式输出以root开头的行,匹配的内容要写在两个斜杠中间

[root@svr7 opt]# sed -n '/^root/p' user
root:x:0:0:root:/root:/bin/bash

例如:用sed查找以root或者bin开头的行,【|】为扩展正则,需加【-r】选项使用扩展正则表达式

[root@svr7 opt]# sed -nr '/^root|^bin/p' user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

例如:输出文件的行数

[root@svr7 opt]# sed -n '$=' user
5

例如:显示行号,=号在sed中可以显示行号

[root@svr7 opt]# sed -n '=' user
1
2
3
4
5

例如:输出第2行,并显示行号

[root@svr7 opt]# sed -n '2p;=' user
1
bin:x:1:1:bin:/bin:/sbin/nologin
2
3
4
5

例如:输出除了第2行的内容,加【!】是取反效果

[root@svr7 opt]# sed -n '2!p' user
root:x:0:0:root:/root:/bin/bash
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

例如:打印奇数行

[root@svr7 opt]# sed -n '1~2p' user
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

例如: 打印偶数行

[root@svr7 opt]# sed -n '2~2p' user
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

常见报错:查看后一行+N无法配合【;】使用

[root@svr7 opt]# sed -n '2p;+1p' user
sed:-e 表达式 #1,字符 5:无法将 +N 或 ~N 作为第一个地址

常见报错:查看单独的2行不能使用【,】分隔,需使用【;】

[root@svr7 opt]# sed -n '2p,4p' user
sed:-e 表达式 #1,字符 3:命令后含有多余的字符

常见报错:取反格式错误

[root@svr7 opt]# sed -n '2p!' user
sed:-e 表达式 #1,字符 3:命令后含有多余的字符


示例:指令d实现对应行的删除并输出(只作输出,不更改源文件)

例如:删除第2行

[root@svr7 opt]# sed -n '2d' user     //删除操作,不能加-n,否则看不到输出
[root@svr7 opt]# sed '2d' user    //删除第2行
root:x:0:0:root:/root:/bin/bash
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

例如:删除第3行、第4行以外的所有行

[root@svr7 opt]# sed '3,+1!d' user
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

例如:删除第3~5行

[root@svr7 opt]# sed '3,5d' user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

 例如:删除包含nologin的行

[root@svr7 opt]# sed '/nologin/d' user
root:x:0:0:root:/root:/bin/bash

例如:删除以nologin结尾的行

[root@svr7 opt]# sed '/nologin$/d' user
root:x:0:0:root:/root:/bin/bash

例如:删除文件的最后一行

[root@svr7 opt]# sed '$d' user
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

例如:删除空行

[root@svr7 opt]# sed '/^$/d' user
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

例如:删除第2行,并显示剩余行的行号

[root@svr7 opt]# sed -n '2d;=' user   //删除第2行,并显示剩余行的行号
1
3
4
5

例如:删除第2行之外的行,并显示剩余行的行号

[root@svr7 opt]# sed -n '2!d;=' user
2

示例:指令s实现对应文本的替换(只作输出,不更改源文件)
[root@svr7 opt]# cat test.txt    //测试文件
2017 2011 2018
2017 2017 2024
2017 2017 2017

注意:不指定行数,默认把所有行匹配到的第1个2017替换成6666

[root@svr7 opt]# sed 's/2017/6666/' test.txt
6666 2011 2018
6666 2017 2024
6666 2017 2017

例如:把第2行匹配到的第1个2017替换成6666

[root@svr7 opt]# sed '2s/2017/6666/' test.txt
2017 2011 2018
6666 2017 2024
2017 2017 2017

例如:把第2行匹配到的第2个2017替换成6666

[root@svr7 opt]# sed '2s/2017/6666/2' test.txt
2017 2011 2018
2017 6666 2024
2017 2017 2017

例如:把所有行匹配到的第2个2017替换成6666

[root@svr7 opt]# sed 's/2017/6666/2' test.txt
2017 2011 2018
2017 6666 2024
2017 6666 2017

例如:把含有2024的行匹配到的第2个2017替换成6666

[root@svr7 opt]# sed '/2024/s/2017/6666/2' test.txt
2017 2011 2018
2017 6666 2024
2017 2017 2017

例如:把所有行匹配到的2017替换成6666

[root@svr7 opt]# sed 's/2017/6666/g' test.txt
6666 2011 2018
6666 6666 2024
6666 6666 6666

例如:把第1行第1个2017替换成6666,然后第2行第2个2017替换成6666(【;】分离多个操作)

[root@svr7 opt]# sed '1s/2017/6666/;2s/2017/6666/2' test.txt
6666 2011 2018
2017 6666 2024
2017 2017 2017

注意:使用【;】隔离多个操作,当第一条替换完成并执行第二条替换时,因第1个2017已替换,该行剩下2个2017,第二条替换找第3个2017时就无法找到了;所以匹配该行的第3个2017,需要改成2。 

[root@svr7 opt]# sed '3s/2017/6666/;3s/2017/6666/3' test.txt
2017 2011 2018
2017 2017 2024
6666 2017 2017

例如:把第3行第1个2017替换成6666,然后第3行的第3个2017替换成6666

[root@svr7 opt]# sed '3s/2017/6666/;3s/2017/6666/2' test.txt
2017 2011 2018
2017 2017 2024
6666 2017 6666[root@svr7 opt]# sed -e '3s/2017/6666/' -e '3s/2017/6666/2' test.txt

例如:将所有的2017都删除(替换为空串)

[root@svr7 opt]# sed 's/2017//g' test.txt2011 20182024

例如:将2~3行的行首加#号

[root@svr7 opt]# sed '2,3s/^/#/' test.txt
2017 2011 2018
#2017 2017 2024
#2017 2017 2017

例如:将1~3行的行尾加>号

[root@svr7 opt]# sed '1,3s/$/>/' test.txt
2017 2011 2018>
2017 2017 2024>
2017 2017 2017>

例如:将1~3行的行首行尾加#号

[root@svr7 opt]# sed '1,3s/$/#/;s/^/#/' test.txt
#2017 2011 2018#
#2017 2017 2024#
#2017 2017 2017#

例如:将每行的行首2改成3

[root@svr7 opt]# sed 's/^2/3/' test.txt
3017 2011 2018
3017 2017 2024
3017 2017 2017

例如:将每行的行首2改成#2

[root@svr7 opt]# sed 's/^2/#2/' test.txt
#2017 2011 2018
#2017 2017 2024
#2017 2017 2017
同等于
[root@svr7 opt]# sed '/^2/s/2/#2/' test.txt

例如:如何把/bin/bash替换成/sbin/sh(替换符)

报错提示:

[root@svr7 opt]# sed '1s//bin/bash//sbin/sh/' user    //直接替换,报错
sed:-e 表达式 #1,字符 8:“s”的未知选项
  • 方法1:使用转义符将所有路径转义,但读起来难识别
[root@svr7 opt]# sed 's/\/bin\/bash/\/sbin\/sh/' user
root:x:0:0:root:/root:/sbin/sh
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
  • 方法2:只要替换符相同即可替换
[root@svr7 opt]# sed '1s#/bin/bash#/sbin/sh#' user
root:x:0:0:root:/root:/sbin/sh
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
同等于
[root@svr7 opt]# sed 's!/bin/bash!/sbin/sh!' user 
[root@svr7 opt]# sed 's@/bin/bash@/sbin/sh@' user

例如:编写脚本,安装httpd服务,要使用82号端口

[root@svr7 opt]# vim httpd_test.sh 
#!/bin/bash
yum -y install httpd &> /dev/null
sed -i '/^Listen 80/s/0/2/' /etc/httpd/conf/httpd.conf   //将以Listen 80开头的行的0换成2
[root@svr7 opt]#systemctl restart httpd
[root@svr7 opt]#systemctl enable httpd

验证:

[root@svr7 opt]# setenforce 0   //执行脚本前要关闭selinux
[root@svr7 opt]# curl  192.168.4.207:82    //脚本执行完后 查看页面
Hello World
[root@svr7 opt]# netstat -ntulp | grep :82   //查看82号端口

四、Sed的文本块概述

应用场景:文件内插入新行、插入多行文本、替换掉指定的整行文本;


示例:指令i,行前插入文本

例如:不指定行号,则逐行全行之前添加文本

[root@svr7 opt]# sed 'i 666' user
666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

例如:在第2行之前添加文本

[root@svr7 opt]# sed '2i 666' user
root:x:0:0:root:/root:/bin/bash
666
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~3行的之前添加文本 666

[root@svr7 opt]# sed '1,3i 666' user
666
root:x:0:0:root:/root:/bin/bash
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
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

例如:在包含root的行之前添加文本 666

[root@svr7 opt]# sed '/root/i 666' user
666
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

例如:在包含root和第3~5行之前增加文本 666

[root@svr7 opt]# sed -e '/root/i 666' -e '3,5i 666' user
666
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
666
daemon:x:2:2:daemon:/sbin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
666
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin


示例:指令a,行后插入文本

例如:不指定行号,则逐行全行之后添加文本

[root@svr7 opt]# sed 'a 777' user 
root:x:0:0:root:/root:/bin/bash
777
bin:x:1:1:bin:/bin:/sbin/nologin
777
daemon:x:2:2:daemon:/sbin:/sbin/nologin
777
adm:x:3:4:adm:/var/adm:/sbin/nologin
777
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
777

例如:在第2行之后添加文本

[root@svr7 opt]# sed '2a 777' user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
777
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

例如:在第2~4行之后添加文本

[root@svr7 opt]# sed '2,4a 777' user
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
777
daemon:x:2:2:daemon:/sbin:/sbin/nologin
777
adm:x:3:4:adm:/var/adm:/sbin/nologin
777
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

例如:在以root开头的行之后添加文本

[root@svr7 opt]# sed '/^root/a 777' user
root:x:0:0:root:/root:/bin/bash
777
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

例如:在包含root的行和第3~4行之后添加文本

[root@svr7 opt]# sed -e '/root/a 777' -e '3,4a 777' user 
root:x:0:0:root:/root:/bin/bash
777
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
777
adm:x:3:4:adm:/var/adm:/sbin/nologin
777
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin


示例:指令c,替换当前行
[root@svr7 opt]# sed 'c 666' user    //替换所有行为666
666
666
666
666
666

例如:替换第1行为666

[root@svr7 opt]# sed '1c 666' user
666
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

例如:替换以bin开头的行为666

[root@svr7 opt]# sed '/^bin/c 666' user
root:x:0:0:root:/root:/bin/bash
666
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行与第3行进行替换成666

[root@svr7 opt]# sed -e '1c 666' -e '3c 666' user
666
bin:x:1:1:bin:/bin:/sbin/nologin
666
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

例如:编写脚本,找到系统中使用bash作为解释器的用户,然后按照“用户名—>密码”的格式存在一个文件中;

  • 思路1:查找到以bash解释器结尾的用户,再用sed替换用户后面【:】所有内容,留下的就是用户名
方法1:
[root@svr7 opt]# grep 'bash$' /etc/passwd | sed 's/:.*//'
root
student
lisi
zhangsan
wangwu
abc01
Tom方法2:
[root@svr7 opt]# sed -n '/bash$/p' /etc/passwd | sed 's/:.*//'方法3:
[root@svr7 opt]# sed -n '/bash$/s/:.*//p' /etc/passwd   //加p显示被替换的行

思路2:查找/etc/shadow中用户名对应的密码行。通过掐头去尾方式过滤出密码

[root@svr7 opt]# grep ‘root:’ /etc/shadow
root:$6$C.j1wjwOSdgoGJnB$UrmNlxKYezuRMnIcrUopqrB46fpWsmvPj0IW82p/CHoETyWnG65lfzhoxikWS0UFIa5pgAK36a5GIpu8R0nbm0::0:99999:7:::

编写脚本

[root@svr7 opt]# vim test05.sh
#!/bin/bash
echo > user    //重定向空,重置文件
user=$(sed -n '/bash$/s/:.*//p' /etc/passwd)   //定义变量user并将替换后的“用户名”结果放入for i in $user
dop=$(grep "$i:" /etc/shadow)   //将每个用户的密码信息过滤出来p1=${p#*:}     //从左到右最短匹配到第一个【:】进行“掐头”p2=${p1%%:*}   //从右到左最长匹配到的【:】进行“掐尾”echo "$i --> $p2" >> user2    //输出“用户—>密码”,并追加重定向user2文件
Done

测试:

[root@svr7 opt]# bash test05.sh
[root@svr7 opt]# cat user2
root --> $6$C.j1wjwOSdgoGJnB$UrmNlxKYezuRMnIcrUopqrB46fpWsmvPj0IW82p/CHoETyWnG65lfzhoxikWS0UFIa5pgAK36a5GIpu8R0nbm0
student --> $6$2s5pSlcENupMYtSO$FVsEEAYXvfiEQ4J3lE18lMCrUfAhLgGZqXYJ.YlVC.93kYJRkPtFjWzKKMKRV3Ef/K6De9VDw9HbU854v7FiZ1
lisi --> !!    //!!为未配置密码
zhangsan --> !!
wangwu --> !!
abc01 --> $6$z52aNPzm$Y7ILzEfUM40U6m0mzCXv9WfrNnRypBZqoheMi5UiUCU1PNGDRnflWLSxVJCMjHwbAd/Z2Z24FI/VATleHVtxd0
Tom --> !!

Sed其他示例:

1)修改IP地址

修改虚拟机XML文件的名称值

[root@svr7 opt]# grep ^IPADDR /etc/sysconfig/network-scripts/ifcfg-eth0
IPADDR=192.168.4.7[root@svr7 opt]# sed -ri '/^IPADDR/s/192.168.1.(.*)/172.16.0.\1' \/etc/sysconfig/network-scripts/ifcfg-eth0

补充:使用【\1】标签可调用本组表达式内第1个用( )保存的匹配结果

2)修改网站根目录

# 将/var/www/html修改为/opt/wwwroot
[root@svr7 opt]# grep "^DocumentRoot" /etc/httpd/conf/httpd.conf
DocumentRoot "/var/www/html"[root@svr7 opt]# sed -i 's#/var/www/hmlt#/opt/wwwroot#' \/etc/httpd/conf/httpd.conf

小结:

本篇章节为【第二阶段】SHELL-DAY4 的学习笔记,这篇笔记可以初步了解到 grep、egrep的使用,基本/扩展正则、sed的使用(非交互、逐行处理、常用命令与选项)。


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/412932.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于深度学习的单目标跟踪系统

基于深度学习的单目标跟踪&#xff0c;效果吊打传统算法&#xff0c;3060显卡上达到实时&#xff0c;代码python和c两个版本都有。 基于深度学习的单目标跟踪系统是一种先进的计算机视觉技术&#xff0c;它可以实现实时的、高精度的目标跟踪。与传统的基于特征匹配或模板匹配的…

LED的使用寿命评估

一&#xff0e;前言 LED光源随着时间的推移&#xff0c;输出光功率会逐渐衰减。在某一时间点&#xff0c;当LED发出的光衰减到一定水平&#xff0c;就无法满足应用要求。因此&#xff0c;常遇见客户会索取产品中LED光源的使用寿命数据。那么怎样确认LED的使用寿命呢&#xff1…

MySQL5.6迁移到DM8

注意&#xff1a; MySQL 5.7 与 MySQL 8.0 的语法有所区别&#xff0c;本文档是将MySQL5.6迁移到DM8。 迁移前准备 源库 数据库信息 统计源端业务库要迁移的数据量、字符编码、归档保留等信息。 内容 说明 备注 数据库架构 单机 节点数 1 数据库版本 MySQL 5.6…

UE5 摄像机图像采集到材质 映射到 UI 和 物体表面

一.创建SceneCapture2D的组件 二.创建用于 映射的 贴图 三.将RenderTarget贴图放到SceneCapture2D的摄像机上Scene Capture的TextureTarget 四.这个时候的映射贴图&#xff0c;产生的材质可以直接。放到Plane上。 五&#xff0c;但是如果要用于UI,还需要更改SceneCapture2D的摄…

C语言基础(二十七)

1、位字段&#xff08;Bit-fields&#xff09;也是一种数据结构&#xff0c;允许在结构体&#xff08;struct&#xff09;或联合体&#xff08;union&#xff09;中定义其成员占用特定的位数。对于需要精确控制内存布局或处理硬件寄存器映射等场景非常有用。位字段使得开发者能…

WebRTC协议下的视频汇聚融合技术:EasyCVR视频技术构建高效视频交互体验

视频汇聚融合技术是指将来自不同源、不同格式、不同网络环境的视频流进行集中处理、整合和展示的技术。随着视频监控、远程会议、在线教育、直播娱乐等领域的快速发展&#xff0c;视频数据的规模急剧增长&#xff0c;对视频处理能力和效率提出了更高要求。视频汇聚融合技术通过…

GAMES202——作业3 Screen Space Ray Tracing

任务 为场景实现屏幕空间的全局光照效果 1.直接光照&#xff1a; 实现ssrFragmentShader中的EvalDiffuse(wi, wo, uv) 和EvalDirectionalLight(uv) 函数&#xff0c;并在 main 函数中实现直接光照的效果。 2.屏幕空间光线求交&#xff1a;实现RayMarch(ori, dir, out hitPos) …

C语言初阶 --- 数据在内存中的存储

&#x1f388; 个人主页&#x1f449;&#xff1a;tbRNA-CSDN博客 &#x1f4af; 个人简介&#xff1a;在校大学生一枚&#x1f48b;. &#x1f60d; 希望我的文章对大家有着不一样的帮助&#xff0c;欢迎大家关注我&#xff0c;感谢大家的多多支持&#xff01; &#x1f389; …

前端面试题每日一练,测测你对JavaScript对象继承和 Object.entries() 的理解

今天的挑战题目涉及到JavaScript中的原型链 (prototype chain) 和 Object.entries() 方法的使用。我们将通过一个对象继承的例子来探索如何使用 Object.entries() 获取对象的自身可枚举属性&#xff0c;并进行处理。让我们一起分析这段代码&#xff0c;看看它会输出什么以及为什…

碎碎念之Android中CPU架构arm-v8a、arm-v7a、x86

0 碎碎念 之前写博客都是为了复习基础知识&#xff0c;不过好像也忘得很快hh。 以后估计会写点感兴趣的自己碎碎念&#xff0c;缓解下emo的心情。&#xff08;不像之前的博客&#xff0c;这些博客不准备复现也不贴代码所以不一定对&#xff0c; 仅供个人参考 &#xff09; 现在…

JMeter Plugins之内网插件问题解决

JMeter Plugins之内网插件问题解决 背景 在我司内部进行JMeter工具进行性能脚本开发时&#xff0c;为了提高测试效率&#xff0c;我们会用到部分JMeter提供的插件&#xff0c;但是在我司内网的情况下&#xff0c;我们如果直接点击JMeter界面右上角的插件按钮 弹出来的JMeter…

Python-MNE-源空间和正模型07:修复BEM和头表面

有时在创建BEM模型时&#xff0c;由于可能出现的一系列问题(例如&#xff0c;表面之间的交叉)&#xff0c;表面需要手动校正。在这里&#xff0c;我们将看到如何通过将表面导出到3D建模程序blender&#xff0c;编辑它们&#xff0c;并重新导入它们来实现这一点。我们还将给出一…

图形化编程系统学习10

项目需求&#xff1a; 点击绿旗&#xff0c;可以使用键盘控制小兔子在地图上移动&#xff0c;收集食物&#xff0c;但只能在黄色道路上移动。 食物碰到小兔子会变大后隐藏&#xff0c;并发出声音。 收集完所有食物&#xff0c;回到温暖的小窝 。 思路解析 1、添加背景和角色…

事半功倍:利用增强现实提高工作效率

人们通常认为增强现实只是游戏中的一个强大的功能&#xff0c;然而&#xff0c;研究表明&#xff0c;增强现实在提高工厂的效率和生产力方面也发挥着重要作用。不管增强现实、虚拟现实还是混合现实都能很好地模拟工厂的工作场景&#xff0c;这对于培训、运营、安全和研发方面的…

OpenCV小练习:人脸检测

OpenCV自带人脸检测模型&#xff0c;拿来就能用。所以“人脸检测”这个任务对于OpenCV而言真是太简单了——感叹一下&#xff1a;OpenCV太强大了&#xff01;相关的介绍文章在网上可以搜到很多&#xff0c;原本我觉得没必要再写一篇了。结果我在写练习代码的时候&#xff0c;还…

如何使用 Pytest 进行测试

Pytest 是一个强大的Python测试框架&#xff0c;支持简单单元测试和复杂的功能测试。它具有灵活的断言表达式、支持参数化测试、强大的插件生态系统等特点。 二、环境搭建 1、安装 Pytest&#xff1a; pip install pytest安装完成后&#xff0c;可以通过命令行检查是否安装成…

Adobe DC 2022提示无法识别的错误 - 解决方案

Adobe DC 2022提示无法识别的错误 - 解决方案 问题解决方案更改安装&#xff08;推荐&#xff09;重新安装&#xff08;推荐&#xff09;降级安装&#xff08;不推荐&#xff09; 问题 使用Adobe DC 2022合并图片创建PDF时&#xff0c;会提示无法识别的错误&#xff0c;这是因…

同步技术难点

在Java中&#xff0c;同步技术主要用于控制多个线程对共享资源的访问&#xff0c;以避免数据不一致和线程安全问题。然而&#xff0c;同步技术也带来了一些难点&#xff0c;主要包括以下几个方面&#xff1a; 死锁&#xff08;Deadlock&#xff09;&#xff1a; 死锁是同步技术…

Python私教张大鹏FastAPI开源框架和项目第一次整理 20240830

去我的Github搜fastzdp开头的&#xff1a;https://github.com/zhangdapeng520?tabrepositories&qfastzdp&type&language&sort fastzdp_api&#xff1a;基于FastAPI二次开发的HTTP REST API 框架。目前刚开始开发&#xff0c;这里面主要记录了FastAPI的一些基础…

大一新生入学证件照采集,手机拍照轻松搞定收集

又到了一年一度大中专院校新生入学的时候了&#xff0c;在开学时很重要的一项工作就是新生照片采集。证件照采集是为了建立学生学籍档案、校园门禁系统登记、校园卡制发、大学四级英语考试报名等&#xff0c;往往要求全校新生使用统一的证件照尺寸、颜色背景&#xff0c;甚至是…