深入理解linux操作系统---第11讲 bshell编程

11.1 正则表达式

11.1.1 字符集

正则表达式的字符集包含三类核心要素:

  1. 普通字符:直接匹配单个字符,如a匹配字母a
  2. 范围字符集[a-z]匹配所有小写字母,[0-9A-F]匹配十六进制数字
  3. 预定义字符集\d等价于[0-9]\w匹配字母/数字/下划线,\s匹配空格

特殊符号示例:

  • [^abc]表示排除a/b/c的任意字符
  • [a-zA-Z]覆盖所有英文字母

11.1.2 Shell正则表达式

与通用正则表达式的差异:

  • 通配符转义*在Shell中表示任意字符序列,需用\*匹配字面量星号
  • 边界控制^匹配行首,$匹配行尾,^$表示空行
  • POSIX扩展语法:需添加-E参数支持+?等扩展元字符

示例:grep -E 'error|warning' log.txt 匹配包含error或warning的行


11.2 流编辑(sed)

11.2.1 功能及用法

  • 在线编辑:逐行处理文本,默认输出到屏幕不修改原文件
  • 核心操作:替换(s)、删除(d)、插入(i)、追加(a)
  • 典型场景:批量修改配置文件、删除注释行、提取日志关键字段

11.2.2 参数与说明

参数作用
-n抑制默认输出,常与p命令配合使用
-i.bak修改文件前创建备份(扩展名可自定义)
-e串联多个编辑命令,如sed -e 's/a/A/' -e 's/b/B/'
-r启用扩展正则表达式(避免转义符\

11.2.3 脚本命令

  • 地址定位1,5d删除1-5行,/error/d删除含error的行
  • 暂存空间h复制到暂存区,G追加暂存内容
  • 条件执行3!d保留第三行,删除其他行

11.2.4 sed示例

  1. 替换文本
    sed 's/old/new/g' file.txt 全局替换old为new
  2. 删除空行
    sed '/^$/d' input.log
  3. 行内编辑
    sed '2s/word/WORD/' 仅修改第二行的首个word

11.3 模式搜索与处理(awk)

11.3.1 功能及用法

  • 结构化处理:自动按分隔符切分字段(默认空格/Tab)
  • 编程能力:支持变量、循环、条件判断,适合生成报表
  • 典型场景:统计访问日志IP频次、计算数据列平均值

11.3.2 参数说明

参数功能
-F ':'指定字段分隔符为冒号
-f script从文件加载awk脚本
-v var=val定义变量供脚本使用

11.3.3 记录和域

  • 记录(Record) :默认以换行符分隔,可通过RS变量修改
  • 字段(Field) :$1表示第一列,$NF表示最后一列

11.3.4 变量

  • 内置变量
    NR当前行号,FILENAME当前文件名
    FS输入分隔符,OFS输出分隔符
  • 自定义变量
    awk -v count=0 '/pattern/{count++} END{print count}'

11.3.5 操作符

类型运算符
算术+ - * / % **
逻辑`&&
字符串连接"hello" "world 自动拼接

11.3.6 控制语句

  • 条件分支

    {if ($3 > 100) print "High"; else print "Normal"}
    
  • 循环结构

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

11.3.7 常用函数

函数作用
length($0)获取当前行长度
substr(str,start,len)截取子字符串
gsub(/old/,"new")全局替换

11.3.8 awk程序执行

  • 三阶段流程
    BEGIN{}初始化 → 逐行处理 → END{}汇总结果
  • 调试技巧
    使用print输出中间变量,或通过awk --debug启动调试模式

11.4 Bourne shell及其编程

11.4.1 特殊字符

字符作用转义方法
$变量引用\$或单引号
*通配符\*或双引号
>输出重定向\>或引号包裹

11.4.2 变量与参数

  • 变量类型

    • 用户变量:name="value"
    • 位置参数:$1第一个参数,$#参数总数
    • 环境变量:PATHHOME通过export导出
  • 参数扩展
    ${var:-default} 变量为空时返回默认值

11.4.3 shell的状态

  • 退出状态码
    0表示成功,非零值表示错误类型
  • 获取方式
    $?获取上条命令的退出状态

11.4.4 shell的调用与变量传递

  • 父子进程
    子进程继承父进程环境变量,但不继承普通变量
  • 跨脚本传参
    通过export导出变量,或通过命令行参数传递

11.4.5 shell程序设计

  • 流程控制
    if [ condition ]; thencommands
    elif [ condition2 ]; thencommands
    elsecommands
    fi
    

11.4.6 命令行参数与选项的处理

  • getopts用法
    while getopts "a:bc" opt; docase $opt ina) arg=$OPTARG ;;b) flag=1 ;;esac
    done
    

11.4.7 shell程序调试

  • 调试模式
    sh -x script.sh 显示每条命令执行过程
  • 日志记录
    exec > debug.log 2>&1 重定向所有输出到文件

11.4.8 shell脚本格式规范

  1. Shebang声明#!/bin/sh
  2. 注释规则:以#开头,解释复杂逻辑
  3. 代码缩进:使用4空格增强可读性
  4. 错误处理set -e遇到错误立即退出

11.5 练习题

11.5.1 思考题

(1)正则表达式可用于模式匹配与搜索,常见的正则表达式有几类?BRE的正则表达式可完全使用于ERE吗?

(2)shell是解释语言还是编译语言?

(3)awk的默认域分隔是什么?如何改变awk的域分隔符?

(4)在shell中如何回到刚离开的工作目录?

11.5.2 填空题

(1)grep  -E  '[Hh]enr(y|ietta)' file的功能是(____________)

(2)grep  -v  "^#"  /etc/syslog.conf的作用是(____________)

(3)sed  -e  's/sysman/System Manager/g' <ifile  >ofile的作用是(____________)

(4)sed  '/^$/d;/[[:space:]]*$/d;' <ifile  >ofile的作用是(____________)

(5)awk  -F: '{ print $1 } END { print NF; print NR }' /etc/passwd的作用是(__________)

(6)awk  '{ print toupper($0) }' <ifile  > ofile的作用是(____________)

11.5.3 综合题

(1)试分别用grep、sed和awk实现:对某个脚本文件ifile(比如/etc/profile)进行如下操作:

① 显示其中的所注释行(含#开始的行,或#号前全是白空格开始的行);

② 显示去除了所有注释行的内容;

③ 显示所有的(去掉注释和空行)有效行。

(2)设计一个菜单shell程序,要求:

① 捕获信号1、2、3、15。

② 当收到信号后在终端上显示:”I Received Signal #”,其中#为收到的信号编号。

③ 其他仿sh03.sh。

(3)设有shell程序,内容为:

#!/bin/bash
pkg="tcsh"
hostnamectl | grep -i Ubuntu >/dev/null 2>&1
if [ $? -eq 0 ]; thencmd_q='dpkg -l '; cmd_i='apt  install '
elsecmd_q='rpm -q '; cmd_i='yum  install '
fi
$cmd_q $pkg  >/dev/null 2>&1
if [ $? -eq 0 ]; then echo "Package: $pkg has been installed!"
else    $cmd_i ${pkg}
fi

试写出程序的功能和执行的可能结果。

(4)在UNIX/Linux系统中,环境变量非常重要,试说明(在字符界面下):

① PATH变量的作用,如何得到PATH的值?

② 在UNIX/Linux系统超级用户的环境变量PATH中允许包含当前目录吗?

③ 若在超级用户的当前目录内有可执行文件mypro,如何执行它(写出执行时键盘输入的内容)?

④ 如何使用该命令在后台执行(写出执行时键盘输入的内容)?

(5)设计一个shell程序计算n的阶乘。要求:

① 从命令行接收参数n;

② 在程序开始后立即判断n的合法性,即是否有参数,若有是否为正整数,若非法请给出错误提示;

③ 最后输出计算的结果。

11.5.4 答案

1.思考题

(1)正则表达式可用于模式匹配与搜索,常见的正则表达式有几类?BRE的正则表达式可完全使用在ERE吗?

解:SRE、BRE和ERE;不能。

(2)shell是解释语言还是编译语言?

解:解释语言。

(3)awk的默认域分隔是什么,如何改变awk的域分隔符?

解:白空格;使用-F选项,可以指定域分隔符,而不使用默认。比如-F:将分隔符指定为冒号。

(4)在bshell中如何回到刚离开的工作目录?

解:$ cd ~-   或者  $ cd $OLDPWD

2.填空题

(1)grep  -E  '[Hh]enr(y|ietta)' file的功能是:(_搜索Henry、henry、Henrietta和henrietta_)。

(2)grep  -v  "^#"  /etc/syslog.conf的作用是:(_显示文件的所有不以"^#"开始的行_)。

(3)sed  -e  's/sysman/System Manager/g' <ifile  >ofile的作用是:(将ifile中的所有sysman替换为System Manager后保存到ofile)。

(4)sed  '/^$/d;/^[[:space:]]*$/d;' <ifile  >ofile的作用是:(将删除空行后的ifile内容保存到ofile)。

(5)awk  -F: '{ print $1 } END { print NF; print NR }' /etc/passwd的作用是:(显示/etc/passwd 中的所有用户名,并在最后显示/etc/passwd中的域个数和总行数)。

(6)awk  '{ print toupper($0) }' <ifile  > ofile的作用是:(将ifile的内容全部转换为大写后保存到ofile)。

3.综合题

(1)试分别用grep、sed和awk实现:对某个脚本文件ifile(比如/etc/profile)进行如下操作:

① 显示其中的所注释行(含#开始的行,或#号前全是白空格开始的行);

② 显示去除了所有注释行的内容;

③ 显示所有的(去掉注释和空行)有效行。

解:

# 要求一:显示其中的所注释行(含#开始的行,或#号前全是白空格开始的行)
# grep  '^[[:space:]]*#'  /etc/profile# sed  '/^[[:space:]]*#/!d' < /etc/profile# awk  '/^[[:space:]]*#/ { print $0 }'  /etc/profile# 要求二:显示去除了所有注释行的内容# grep -v  '^[[:space:]]*#' < /etc/profile# sed   '/^[[:space:]]*#/d'  /etc/profile# awk  '!/^[[:space:]]*#/ { print $0 }' < /etc/profile# 要求三:显示所有的(去掉注释和空行)有效行# grep -v -E '(^[[:space:]]*#)|(^[[:space:]]*$)' /etc/profile# sed '/^[[:space:]]*#/d;/^[[:space:]]*$/d' < /etc/profile# awk '!/(^[[:space:]]*#)|(^[[:space:]]*$)/ { print $0 }' /etc/profile

(2)设计一个菜单shell程序,要求:

①捕获信号1、2、3、15;

②当收到信号后在终端上显示:”I Received Signal #”,其中#为收到的信号编号。

③其它仿sh03.sh。

解:实现方法很多,其中一种的代码如下(命名为sh03n.sh):

#!/bin/sh
func1( ){ echo "This is function 1"; }
func2( ){ echo "This is function 2"; }
trap "echo I received SIGNAL: 1 " 1
trap "echo I received SIGNAL: 2 " 2
trap "echo I received SIGNAL: 3 " 3
trap "echo I received SIGNAL: 15 " 15while true; doclearecho -n "
+--------------------------------------------+
|    1. func1     2. func2    0/q/Q.Exit     |
+--------------------------------------------+Please get a choice: ";     read xcase $x in1) func1;;2) func2;; 0|Q|q) exit $?;;*) echo -e "Invalid input: $x \a";;esacread -p "Press Enter to continue: " x
done

(3)设有shell程序内容为(命名为sh17.sh):

#!/bin/bash
pkg="tcsh"
hostnamectl | grep -i Ubuntu >/dev/null 2>&1
if [ $? -eq 0 ]; thencmd_q='dpkg -l '; cmd_i='apt  install '
elsecmd_q='rpm -q '; cmd_i='yum  install '
fi
$cmd_q $pkg  >/dev/null 2>&1
if [ $? -eq 0 ]; then echo "Package: $pkg has been installed!"
else    $cmd_i ${pkg}
fi

试写出程序的功能和执行的可能结果:

解:针对Ubuntu或红帽系统,分别判断软件包tcsh是否已经安装,若没有安装,则安装之。若已经安装则显示

Package: tcsh has been installed!

(4)在UNIX/Linux系统中,环境变量是非常重要,在字符界面下试说明:

①PATH变量的作用,如何得到PATH的值?

②在UNIX/Linux系统的超级用户的环境变量PATH中允许包含当前目录吗?

③若在超级用户的当前目录内有可执行文件mypro,如何执行它(写出执行时键盘输入内容)?

④如何使该命令在后台执行(写出执行时键盘输入内容)?

解:

①PATH为shell命令的搜索路径;可以用echo $PATH显示其值;

②默认情况下,不允许。这样可以保证命令搜索只在PATH规定的路径内进行。

③由②可知,当前路径不在PATH内,所以搜索命令时,当前路径不会被搜索。若要执行当前目录的命令只能带路径执行,方法是

# ./mypro

④在命令的结尾处,回车前使用&符号,比如

# ./mypro &

(5)设计一个shell程序计算n的阶乘。要求:

①从命令行接收参数n;

②在程序开始后立即判断n的合法性,即是否有参数,若有是否为正整数,若非法请给错误提示;

③最后输出计算的结果。

解:方法之一代码如下(命名为sh18.sh):

#!/bin/bash
# 定义用法提示函数
Usage(){ echo -e "Usage:\n$0 Integer"; }# 参数数量检查(无参数时提示用法)
if [ $# -eq 0 ]; then Usageexit 1
fi# 使用awk验证输入是否为纯数字
x=`echo $1 | awk '/^[[:digit:]]+$/ {print $1}'`# 输入合法时执行计算
if [ ! -z "$x" ]; thenf=1  # 初始化阶乘结果x=1  # 初始化循环计数器# 通过while循环累乘计算阶乘while [ $x -le $1 ]; dof=`expr $f \* $x`  # 旧式算术运算x=`expr $x + 1`    # 计数器递增# 注释的优化方案:f=$((f*x++))doneecho $f  # 输出结果
else Usage  # 输入非法时提示用法exit 2
fi

总结  

        掌握BShell编程需要理解正则表达式、流处理工具(sed/awk)以及Shell脚本设计规范。建议通过实际案例(如日志分析、批量重命名)巩固知识,并善用调试工具提高开发效率。

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

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

相关文章

C++中的引用:深入理解与实用示例

文章目录 C中的引用&#xff1a;深入理解与实用示例一、引用的基本概念二、引用作为别名的应用三、引用作为函数参数四、指针与引用的区别五、常量引用六、引用与返回值七、总结 C中的引用&#xff1a;深入理解与实用示例 在C编程中&#xff0c;“引用”是一个强大而重要的概念…

C#委托介绍

委托可以将方法作为参数传递&#xff0c;同时委托也可以自己作为参数传递 委托可分为自定义委托delegate 无返回值的Action 与有返回值的Func委托 也有匿名委托与Lamada 委托支持多播是事件的基础 用处如在分线程调用主线程的UI invoke public delegate string Say(stri…

Node.js 模块导入的基本流程

Node.js 模块导入的基本流程&#xff0c;主要是 CommonJS 模块加载机制&#xff08;即使用 require()&#xff09;的内部执行步骤。下面我用清晰的结构给你梳理一下这个过程&#xff1a; ✅ Node.js 模块导入的基本流程&#xff08;使用 require()&#xff09; const someModu…

n8n 中文系列教程_02. 自动化平台深度解析:核心优势与场景适配指南

在低代码与AI技术深度融合的今天&#xff0c;n8n作为开源自动化平台正成为开发者提效的新利器。本文深度剖析其四大核心技术优势——极简部署、服务集成、AI工作流与混合开发模式&#xff0c;并基于真实场景测试数据&#xff0c;厘清其在C端高并发、多媒体处理等场景的边界。 一…

【C++ Qt】信号和槽(内配思维导图 图文并茂 通俗易懂)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是Qt中的第三章&#xff0c;也是我们理解Qt中必备的点 信号槽&#xff0c;它本质由信号和槽两个来实现&#xff0c;其中将细致的讲述如何自定义信号…

【项目】基于MCP+Tabelstore架构实现知识库答疑系统

基于MCPTabelstore架构实现知识库答疑系统 整体流程设计&#xff08;一&#xff09;Agent 架构&#xff08;二&#xff09;知识库存储&#xff08;1&#xff09;向量数据库Tablestore&#xff08;2&#xff09;MCP Server &#xff08;三&#xff09;知识库构建&#xff08;1&a…

免费将静态网站部署到服务器方法(仅支持HTML,CSS,JS)

原视频链接&#xff1a;把HTML免费部署到网站上&#xff0c;实现别人也能访问的教程来啦QAQ_哔哩哔哩_bilibili 注意&#xff1a;仅支持HTML、CSS、JS。不支持Vue等框架。 1.打开网站www.wordpress.org 点击红框按钮 点击红框按钮下载wordpress模板文件并解压。 将自己编写的…

游戏引擎学习第235天:在 Windows 上初始化 OpenGL

奇怪有问题 之前没注意到 这个问题是Count 0 GlobalConstants_Renderer_UsedDebugCamer 打开的话会有Bug Count是零的话就不让排序了 game.h: 查阅 TODO 列表 大家好&#xff0c;欢迎来到 game Hero&#xff0c;这是一档我们在直播中一起编写完整游戏的节目。不幸的是&a…

使用eCharts绘制中国地图

eCharts官网&#xff1a;https://echarts.apache.org/zh/index.html 1. 首先新建一个html页面&#xff0c;并引入echarts <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-…

Linux与Anaconda环境部署与管理(运维交接)

文章目录 一、前言二、Linux基础命令三、进程管理与监控四、后台任务与服务管理五、Anaconda环境管理六、JAR包的运行与管理七、网络与端口映射八、安全与权限管理九、故障排查与日志分析十、附录 一、前言 本文将详细介绍Linux系统下的常用命令以及Anaconda环境管理&#xff…

php:实现压缩文件上传、解压、文件更名、删除上传临时文件、存入数据库等操作

一、效果图 1.上传文件 2.压缩包文件 3.itemno1文件 二层结构 或 三层结构 4.上传到系统路径\ItemNo 5.更名后的itemno1文件(命名:当天日期+六位随机数) 二、普通实现 1、内容介绍 含有两种结构 二层结构:zip->料号文件夹->料号文件三层结构:zip->总文件夹-&g…

基于大语言模型的减肥健身计划系统设计与实现

基于大语言模型的减肥健身计划系统设计与实现 【包含内容】 【一】项目提供完整源代码及详细注释 【二】系统设计思路与实现说明 【三】功能演示与部署指南 【技术栈】 ①&#xff1a;系统环境&#xff1a;Python 3.x Django 4.2 ②&#xff1a;开发环境&#xff1a;Web服务…

c#开发大冲锋游戏登录器

1 前言 本文主要分享登录器的简要开发过程&#xff0c;只适合小白选手&#xff0c;高手请自动避让。 此项目是复刻大冲锋计划中的子集。 &#xff08;注&#xff1a;大冲锋是迅雷代理的一款次时代多职业第一人称FPS射击游戏&#xff0c;目前已经关服嗝屁。&#xff09; 2 …

Linux[基础指令][2]

Linux[基础指令][2] cp(复制) 格式:cp [-rf] 源文件 {普通文件,目录} 拷贝 cp -r 递归拷贝目录 蓝色为目录,白色为具体文件 拷贝后面加一个不存在的文件会新建文件再拷贝 cp -ir -i是覆盖的时候询问 如果目标文件存在就会覆盖原有文件 mv(重命名/剪切) 格式:mv 源文件…

React18+ 项目搭建-从初始化、技术选型到开发部署的全流程规划

搭建一个 React 项目需要从项目初始化、技术选型到开发部署的全流程规划。以下是详细步骤和推荐的技术栈&#xff1a; 一、项目初始化 1. 选择脚手架工具 推荐工具&#xff1a; Vite&#xff08;现代轻量级工具&#xff0c;支持 React 模板&#xff0c;速度快&#xff09;&am…

人工智能学习框架完全指南(2025年更新版)

一、核心框架分类与适用场景 人工智能框架根据功能可分为深度学习框架、机器学习框架、强化学习框架和传统工具库,以下是主流工具及选型建议: 1. 深度学习框架 (1)PyTorch 核心优势:动态计算图、灵活性强,适合科研与快速原型开发,支持多模态任务(如NLP、CV) 。技术生…

MySQL 详解之事务管理

MySQL 详解之事务管理 在数据库领域,事务是一个核心概念,它确保了数据操作的可靠性和一致性。尤其是在处理涉及多个步骤且必须全部成功或全部失败的业务场景时,事务更是不可或缺。本篇文章将深入探讨 MySQL 中的事务管理,帮助您全面理解事务的工作原理及其在实际应用中的重…

SpringAI+DeepSeek大模型应用开发——5 ChatPDF

ChatPDF 知识库 RAG检索增强 由于训练大模型非常耗时&#xff0c;再加上训练语料本身比较滞后&#xff0c;所以大模型存在知识限制问题&#xff1a; 知识数据比较落后&#xff0c;往往是几个月之前的&#xff1b;不包含太过专业领域或者企业私有的数据&#xff1b; 为了解决…

SSH 互信被破坏能导致 RAC 异常关闭吗

一、 SSH 互信和 RAC 的关系 1、SSH 互信对 RAC 的作用 Oracle 11g R2 在安装 Grid Infrastructure 的时候&#xff0c;能够通过安装程序配置节 点间的 SSH 用户等效性&#xff0c;之所以要在安装之前配置 SSH 用户等效性&#xff0c;是为了能 够在安装前使用 C…

【数字图像处理】立体视觉信息提取

双目立体视觉原理 设一个为参考平面&#xff0c;一个为目标平面。增加了一个摄像头后&#xff0c;P与Q在目标面T上有分别的成像点 双目立体视觉&#xff1a;从两个不同的位置观察同一物体&#xff0c;用三角测量原理计算摄像机到该物体的距离的 方法 原理&#xff1a;三角测量…