文章目录
Linux随笔6-软件安装以及sed和bash变量删除、替换
关于Linux上的软件安装,主要途径有源码编译安装、二进制文件安装(比如RedHat以及其衍生版的二进制安装包.rpm以及Debian以及其衍生版的二进制安装包.deb)。而二进制安装包之间,往往会有依赖关系,为了解决各个二进制安装包之间的依赖关系,Debian发布了apt
工具用于自动解决所安装的软件包的依赖关系;而RedHat后续也发布了与其发布版对应的yum
工具来解决所安装软件包的依赖关系。这两个工具都需要依赖于后端的软件仓库,才能自动下载依赖的其他软件包。所以这里将会以yum
工具的软件仓库配置进行介绍。随后会以编译安装http-2.4的实例过程说明如何通过源代码编译安装所需要的软件,以及安装之后的环境设置。
随后将会结合具体的示例介绍sed
命令以及bash的变量内容替换、删除和截取。
1. 自建yum仓库
关于yum仓库仓库的配置,可以通常是通过安装系统的光盘镜像iso文件或者通过网络源进行配置,此处基于CentOS 7.6分别进行介绍。
1.1. 构建yum仓库的网络源
网络源采用fedora项目的EPEL(Extra Packages for Enterprise Linux)企业级Linux扩展软件源,从fedora项目网站下载对应版本的EPEL源的rpm包,https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm,具体如下:
[root@c7u6m1 opt]# wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm --2021-04-17 11:17:11-- https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm Resolving dl.fedoraproject.org (dl.fedoraproject.org)... 38.145.60.23, 38.145.60.24, 38.145.60.22 Connecting to dl.fedoraproject.org (dl.fedoraproject.org)|38.145.60.23|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 15448 (15K) [application/x-rpm] Saving to: ‘epel-release-latest-7.noarch.rpm’ 100%[=======================================================================================================>] 15,448 56.9KB/s in 0.3s 2021-04-17 11:17:18 (56.9 KB/s) - ‘epel-release-latest-7.noarch.rpm’ saved [15448/15448] [root@c7u6m1 opt]# ls containerd epel-release-latest-7.noarch.rpm rh [root@c7u6m1 opt]# rpm -ivh epel-release-latest-7.noarch.rpm Preparing... ################################# [100%] file /etc/yum.repos.d/epel-testing.repo from install of epel-release-7-13.noarch conflicts with file from package epel-release-7-11.noarch file /etc/yum.repos.d/epel.repo from install of epel-release-7-13.noarch conflicts with file from package epel-release-7-11.noarch file /usr/lib/systemd/system-preset/90-epel.preset from install of epel-release-7-13.noarch conflicts with file from package epel-release-7-11.noarch [root@c7u6m1 opt]# rpm -qa | egrep epel epel-release-7-11.noarch [root@c7u6m1 opt]# [root@c7u6m1 opt]# rpm -Uvh epel-release-latest-7.noarch.rpm Preparing... ################################# [100%] Updating / installing... 1:epel-release-7-13 ################################# [ 50%] Cleaning up / removing... 2:epel-release-7-11 ################################# [100%] [root@c7u6m1 opt]#
由于此前安装过epel的rpm包,所以使用
rpm -ivh
安装的时候提示两个版本冲突。所以使用rpm -Uvh
进行更新安装。安装完成之后,查看这个包中提供了哪些文件:[root@c7u6m1 yum.repos.d]# rpm -ql epel-release /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel.repo /usr/lib/systemd/system-preset/90-epel.preset /usr/share/doc/epel-release-7 /usr/share/doc/epel-release-7/GPL [root@c7u6m1 yum.repos.d]# [root@c7u6m1 yum.repos.d]# ls /etc/yum.repos.d/ | egrep epel epel.repo epel-testing.repo
至此,就安装完成了。
查看EPEL的镜像信息:
[root@c7u6m1 yum.repos.d]# yum repolist Loaded plugins: fastestmirror, langpacks Repository epel is listed more than once in the configuration Repository epel-debuginfo is listed more than once in the configuration Repository epel-source is listed more than once in the configuration Loading mirror speeds from cached hostfile repo id repo name status DVD-REPO CentOS 7.6 DVD Repository 4,021 base/7/x86_64 CentOS-7 - Base 10,072 docker-ce-stable/7/x86_64 Docker CE Stable - x86_64 112 epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 13,580 extras/7/x86_64 CentOS-7 - Extras 468 updates/7/x86_64 CentOS-7 - Updates 1,932 repolist: 30,185 [root@c7u6m1 yum.repos.d]#
上述就构建好了网络源作为yum的软件包仓库。
1.2. 构建yum仓库的本地源
本地软件镜像源
-
向虚拟机中附加光盘镜像并挂载镜像
向KVM虚拟机中附加ISO光盘镜像,具体命令如下所示:
[root@localhost CentOS7.6]# virsh attach-disk c7u6m1 ${PWD}/CentOS-7-x86_64-DVD-1810.iso hda --type cdrom --mode readonly Disk attached successfully [root@localhost CentOS7.6]# virsh dumpxml c7u6m1 | egrep -C 3 CentOS </disk> <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/data/iso/CentOS7.6/CentOS-7-x86_64-DVD-1810.iso' index='5'/> <backingStore/> <target dev='hda' bus='ide'/> <readonly/> [root@localhost CentOS7.6]#
查看附加好的光盘镜像:
[root@c7u6m1 ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sr0 11:0 1 4.3G 0 rom vda 252:0 0 40G 0 disk ├─vda1 252:1 0 512M 0 part /boot ├─vda2 252:2 0 1G 0 part [SWAP] └─vda3 252:3 0 38.5G 0 part └─vg0-root 253:0 0 38.5G 0 lvm / [root@c7u6m1 ~]# ls -lh /dev/cdrom lrwxrwxrwx 1 root root 3 Apr 17 09:56 /dev/cdrom -> sr0 [root@c7u6m1 ~]# ls -lh /dev/sr0 brw-rw---- 1 root cdrom 11, 0 Apr 17 09:56 /dev/sr0 [root@c7u6m1 ~]#
上述的
lsblk
命令的输出中,sr0就是附加的光盘镜像。在上述的虚拟机c7u6m1中挂载cdrom到/media目录下,具体如下所示:
[root@c7u6m1 ~]# mount -t iso9660 -o loop /dev/sr0 /media/ [root@c7u6m1 ~]# df -hT Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/vg0-root xfs 39G 4.9G 34G 13% / devtmpfs devtmpfs 988M 0 988M 0% /dev tmpfs tmpfs 1000M 0 1000M 0% /dev/shm tmpfs tmpfs 1000M 25M 975M 3% /run tmpfs tmpfs 1000M 0 1000M 0% /sys/fs/cgroup /dev/vda1 xfs 509M 129M 381M 26% /boot tmpfs tmpfs 200M 0 200M 0% /run/user/0 /dev/loop0 iso9660 4.3G 4.3G 0 100% /media [root@c7u6m1 ~]# ls -F /media/ CentOS_BuildTag EULA images/ LiveOS/ repodata/ RPM-GPG-KEY-CentOS-Testing-7 EFI/ GPL isolinux/ Packages/ RPM-GPG-KEY-CentOS-7 TRANS.TBL [root@c7u6m1 ~]#
上述就完成了对虚拟机的光盘镜像附加、挂载操作。接下来使用挂载的文件系统中的内容配置本地软件仓库。为此,需要先创建.repo格式的配置文件。
-
创建yum源配置文件
在/etc/yum.repos.d目录下创建文件c7u6-local.repo,其内容如下:
[root@c7u6m1 ~]# cat /etc/yum.repos.d/c7u6-local.repo [DVD-REPO] name=CentOS 7.6 DVD Repository baseurl=file:///media enabled=1 gpgcheck=1 gpgkey=file:///media/RPM-GPG-KEY-CentOS-7
由于repo配置文件的的固定格式,只需要列出上述配置文件中的字段即可。各字段含义解释如下:
- [DVD-REPO]:指定了这个软件仓库的ID,也是后续操作的时候经常会用到的,会使用这个仓库ID来引用特定的软件仓库。注意:中括号中不能有空格
- name=:指定了软件仓库的名称,在命令行中用不到该字段的信息,类似于对该仓库的注释、说明信息,该字段中可以有空格
- baseurl=:指定了软件仓库的路径,如果是本地文件系统路径,则需要以file://开头,如果是网络仓库,则需要以http://或者https://开头。完整格式为baseurl=url://server1/path/to/repository
- enabled=:可选值有两个,分别为0和1。如果为0,表示禁用该软件仓库;如果为1,表示启用该软件仓库
- gpgcheck=:可选值有两个,分别为0和1。如果为0,则表示禁用gpg检查;如果为1,表示在安装该仓库的软件时启用gpg检查,以便确保安装的软件包的一致性和安全性
- gpgkey=:指定gpgcheck所用的gpgkey文件的路径,使用该key文件验证所安装的该仓库中的软件包
上述的这几个字段是最常用的字段,使用这些字段就可以完成本地软件仓库的配置工作。更多的其他字段信息以及解释,参见
man yum.conf
的帮助手册。构建完镜像仓库的配置文件之后,缓存镜像信息:
[root@c7u6m1 ~]# vim /etc/yum.repos.d/c7u6-local.repo [root@c7u6m1 ~]# yum makecache Loaded plugins: fastestmirror, langpacks Repository epel is listed more than once in the configuration Repository epel-debuginfo is listed more than once in the configuration Repository epel-source is listed more than once in the configuration Loading mirror speeds from cached hostfile DVD-REPO | 3.6 kB 00:00:00 base | 3.6 kB 00:00:00 [root@c7u6m1 media]# yum repolist Loaded plugins: fastestmirror, langpacks Repository epel is listed more than once in the configuration Repository epel-debuginfo is listed more than once in the configuration Repository epel-source is listed more than once in the configuration Loading mirror speeds from cached hostfile repo id repo name status DVD-REPO CentOS 7.6 DVD Repository 4,021 base/7/x86_64 CentOS-7 - Base 10,072
使用配置好的本地光盘镜像安装软件:
[root@c7u6m1 media]# yum repository-packages DVD-REPO list | egrep xz Repository epel is listed more than once in the configuration Repository epel-debuginfo is listed more than once in the configuration Repository epel-source is listed more than once in the configuration xz-devel.x86_64 5.2.2-1.el7 DVD-REPO [root@c7u6m1 media]# yum install xz-devel Loaded plugins: fastestmirror, langpacks Repository epel is listed more than once in the configuration Repository epel-debuginfo is listed more than once in the configuration Repository epel-source is listed more than once in the configuration Loading mirror speeds from cached hostfile Resolving Dependencies --> Running transaction check ---> Package xz-devel.x86_64 0:5.2.2-1.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================= Installing: xz-devel x86_64 5.2.2-1.el7 DVD-REPO 46 k Transaction Summary ================================================================================================================================================= Install 1 Package Total download size: 46 k Installed size: 165 k Is this ok [y/d/N]: y Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : xz-devel-5.2.2-1.el7.x86_64 1/1 Verifying : xz-devel-5.2.2-1.el7.x86_64 1/1 Installed: xz-devel.x86_64 0:5.2.2-1.el7 Complete! [root@c7u6m1 media]#
上述通过安装xz-devel这个软件包,验证了配置好的软件仓库是可以正常工作的。
至此,本地仓库就构建好了,并且可以用其中的软件包通过yum
命令进行软件安装操作了。
2. 编译安装
以httpd-2.4为例,进行源代码的编译安装,首先下载对应版本的源代码,然后进行编译安装,最后对于安装好的环境进行配置并验证安装效果。
2.1. 下载httpd-2.4
首先从https://mirrors.bfsu.edu.cn/apache//httpd/httpd-2.4.46.tar.bz2下载httpd-2.4的源代码压缩包。
具体如下:
[root@c7u6m1 softwares]# wget https://mirrors.bfsu.edu.cn/apache//httpd/httpd-2.4.46.tar.bz2 --2021-04-17 14:54:42-- https://mirrors.bfsu.edu.cn/apache//httpd/httpd-2.4.46.tar.bz2 Resolving mirrors.bfsu.edu.cn (mirrors.bfsu.edu.cn)... 39.155.141.16, 2001:da8:20f:4435:4adf:37ff:fe55:2840 Connecting to mirrors.bfsu.edu.cn (mirrors.bfsu.edu.cn)|39.155.141.16|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 7187805 (6.9M) [application/octet-stream] Saving to: ‘httpd-2.4.46.tar.bz2’ 100%[=======================================================================================================>] 7,187,805 9.28MB/s in 0.7s 2021-04-17 14:54:43 (9.28 MB/s) - ‘httpd-2.4.46.tar.bz2’ saved [7187805/7187805] [root@c7u6m1 softwares]# ls httpd-2.4.46.tar.bz2 [root@c7u6m1 softwares]# ls -lh total 6.9M -rw-r--r-- 1 root root 6.9M Aug 5 2020 httpd-2.4.46.tar.bz2
将下载好的源码包解压缩,具体如下:
[root@c7u6m1 softwares]# tar jxvf httpd-2.4.46.tar.bz2 httpd-2.4.46/server/NWGNUmakefile httpd-2.4.46/server/main.c httpd-2.4.46/server/gen_test_char.mak httpd-2.4.46/server/.indent.pro httpd-2.4.46/server/util_expr_scan.l httpd-2.4.46/server/provider.c httpd-2.4.46/server/gen_test_char.dsp httpd-2.4.46/server/Makefile.in httpd-2.4.46/server/util_expr_private.h httpd-2.4.46/server/mpm_common.c httpd-2.4.46/server/util.c httpd-2.4.46/server/util_expr_parse.h httpd-2.4.46/server/request.c ... [root@c7u6m1 softwares]# cd httpd-2.4.46/ [root@c7u6m1 httpd-2.4.46]# ls -F ABOUT_APACHE ap.d CHANGES docs/ httpd.spec libhttpd.dep Makefile.win README srclib/ acinclude.m4 build/ CMakeLists.txt emacs-style include/ libhttpd.dsp modules/ README.cmake support/ Apache-apr2.dsw BuildAll.dsp config.layout httpd.dep INSTALL libhttpd.mak NOTICE README.platforms test/ Apache.dsw BuildBin.dsp configure* httpd.dsp InstallBin.dsp LICENSE NWGNUmakefile ROADMAP VERSIONING apache_probes.d buildconf* configure.in httpd.mak LAYOUT Makefile.in os/ server/ [root@c7u6m1 httpd-2.4.46]#
有了源代码,就可以准备编译安装了。
2.2. 编译安装
在上述的解压缩的目录中,通常会包含README以及INSTALL这两个文件,建议在编译安装之前先仔细阅读这两个文件。README是关于该源代码项目的说明信息,有时也含有安装说明。更多的时候,如何编译安装的说明,都是记录在INSTALL这个文件中。
查看INSTALL文件的内容如下所示:
[root@c7u6m1 httpd-2.4.46]# less INSTALL Quick Start - Unix ------------------ For complete installation documentation, see [ht]docs/manual/install.html or http://httpd.apache.org/docs/2.4/install.html $ ./configure --prefix=PREFIX $ make $ make install $ PREFIX/bin/apachectl start
上述的INSTALL文件中记录了该软件的源码编译安装所需要的命令以及启动服务的方式。其中
./configure
文件是可执行的,可以对安装参数进行自定义。关于支持的选项参数,可以执行命令./configure --help
进行查看。其内容如下:[root@c7u6m1 httpd-2.4.46]# ./configure --help `configure' configures this package to adapt to many kinds of systems. Usage: ./configure [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print `checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for `--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or `..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local/apache2] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, `make install' will install all the files in `/usr/local/apache2/bin', `/usr/local/apache2/lib' etc. You can specify an installation prefix other than `/usr/local/apache2' using `--prefix', for instance `--prefix=$HOME'. ...
更多的输出省略。
上述输出中,最常用的选项就是通过
--prefix=/path/to/install
指定该软件的安装路径。下面选择一些基础参数进行编译安装。分为两个阶段进行介绍:
configure阶段
默认情况下,执行
make install
之后,就是将该软件安装到/usr/local/apache2这个目录下。By default,make install
will install all the files in
/usr/local/apache2/bin, /usr/local/apache2/lib etc. You can specify
an installation prefix other than /usr/local/apache2 using --prefix,
for instance --prefix=$HOME.安装需要的基础环境包:
[root@c7u6m1 httpd-2.4.46]# yum install -y apr apr-devel gcc gcc-c++ pcre pcre-devel pcre-static pcre-tools
安装完上述的基础环境包之后,执行
.configure
命令,具体如下所示:[root@c7u6m1 httpd-2.4.46]# ./configure --prefix=/usr/local/httpd-2.4.46 config.status: creating build/config_vars.sh config.status: creating include/ap_config_auto.h config.status: executing default commands configure: summary of build options: Server Version: 2.4.46 Install prefix: /usr/local/httpd-2.4.46 C compiler: gcc -std=gnu99 CFLAGS: -pthread CPPFLAGS: -DLINUX -D_REENTRANT -D_GNU_SOURCE LDFLAGS: LIBS: C preprocessor: gcc -E [root@c7u6m1 httpd-2.4.46]# [root@c7u6m1 httpd-2.4.46]# echo $? 0 [root@c7u6m1 httpd-2.4.46]#
上述的输出中表示,
./configure
这个步骤正确完成。接下来进行make && make install
的阶段完成安装过程。make && make install阶段
make
和make install
命令均可以通过-j num
指定安装过程同步使用的jobs数。如果不指定-j
选项,则是默认的1个。如果系统有多个核心,通常该值不超过CPU的核心数。多核编译安装比单核安装效率高。具体如下所示:[root@c7u6m1 httpd-2.4.46]# make -j 8 && make -j 8 install make[3]: Leaving directory `/root/softwares/httpd-2.4.46/modules/mappers' make[2]: Leaving directory `/root/softwares/httpd-2.4.46/modules' make[2]: Entering directory `/root/softwares/httpd-2.4.46/support' make[2]: Leaving directory `/root/softwares/httpd-2.4.46/support' make[1]: Leaving directory `/root/softwares/httpd-2.4.46' [root@c7u6m1 httpd-2.4.46]# echo $? 0 [root@c7u6m1 httpd-2.4.46]#
上述的编译安装过程就完成了。检查下安装路径的内容,具体如下:
[root@c7u6m1 httpd-2.4.46]# ls -F /usr/local/httpd-2.4.46/ bin/ build/ cgi-bin/ conf/ error/ htdocs/ icons/ include/ logs/ man/ manual/ modules/ [root@c7u6m1 httpd-2.4.46]#
至此,编译安装过程就完成了。验证下是否可以访问httpd-2.4所提供的web服务。具体如下所示:
先在c7u6m1节点上启动httpd服务,具体如下:
[root@c7u6m1 bin]# ./apachectl start AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.122.2. Set the 'ServerName' directive globally to suppress this message [root@c7u6m1 bin]# [root@c7u6m1 bin]# hostname c7u6m1.localhost.com [root@c7u6m1 bin]# ./apachectl start httpd (pid 32352) already running [root@c7u6m1 bin]#
上述第一次执行
./apachectl start
命令的时候提示主机名不是FQDN名称,所以在第4行设置了临时主机名为FQDN格式,然后再启动该httpd服务即可。上述在服务端启动完成之后,接下来就是在客户端中执行
curl
命令测试到服务器端的连接:root@ubuntu20u04:~/scripts# curl http://192.168.122.2 <html><body><h1>It works!</h1></body></html> root@ubuntu20u04:~/scripts#
上述显示,服务端可以正常提供服务。
3. sed命令和bash环境变量内容替换、删除介绍以及示例
sed
即Stream EDitor,流式编辑器。用于处理输入流、文件、或者是前一条命令的管道输出结果,执行基本的文本转换操作。其不同于交互式全屏编辑器vim
,类似于脚本式的编辑器,无需进行实时交互,所以效率上也更高。sed
作为流式编辑器,是以行为单位进行文本处理,即读入一行,然后对该行进行处理,完成之后将处理结果打印到标准输出;然后再读取后面的一行,并对其进行处理,完成之后将处理结果打印到标准输出;如此循环直到处理完最后一行。
在处理一行的时候,会将当前处理的行临时存储在缓冲区中,即模式空间(Pattern Space)中,随后sed
会对模式空间中的内容进行处理,处理完成之后,将模式空间中的内容打印到标准输出中。接着再以相同的方式处理下一行直到文件末尾或者输入流的最后一行处理完成。由于每次只将一行内容读入到模式空间,所以对于处理很大的文件也没有压力;而vim
则是将整个文件全部读入到内存中进行交互式处理,所以当文件很大的时候,打开文件的过程就会耗时不少。由于sed
是类似于脚本式的行编辑器,所以其处理效率是很高的。
除了模式空间之外,sed
还有一个很重要的保持空间(Hold Space),用于将模式空间的处理结果写入保持空间,而不是打印到标准输出中。加入到保持空间的内容会通过指定的命令一次全部进行输出。
3.1. sed命令基本介绍
sed
命令的基本形式为sed [OPTION]... {script-only-if-no-other-script} [input-file]...
,其中常用的选项如下:
- -n:压制模式空间中的内容,使其不会自动被打印到标准输出流中
- -e script, --expression=script:添加要执行的脚本,用于处理读入行的命令
- -f script_file, --file=script_file:将sed的命令写入到脚本文件中,并执行这些记录在script_file中的命令
- -r:使用拓展正则表达式
- -i [suffix], --in-place[=suffix]:就地修改输入文件input_file,即直接对输入文件进行修改;如果指定了suffix,那么在直接修改之前会使用suffix作为后缀备份输入文件input_file
其中,script的格式为地址范围命令
,即地址范围指定命令的作用域、作用范围;命令指定要执行的操作。
-
地址范围:常见的格式有以下几种
- 未指定地址范围:表示对全文的所有行进行处理
- 单地址:
- #:指定的第#行内容
- $:输入流的最后一行
- /pattern/:被pattern匹配到的每一行
- 地址范围:
- #1,#2:从#1行到#2行的内容;比如3,6表示从第3行到第6行的内容,包含第3行和第6行,意义等效于[3, 6]
- #1,+#2:表示从#1行开始,向后增加#2行的内容;比如3,+6表示从第3行开始,往后数6行到第9行之间的内容,#2表示从第#1行开始的偏移量。同样包括第3行和第9行,意义等效于[3, 9]
- /pat1/,/pat2/:表示从pat1匹配到的行开始,到pat2匹配到的行以及这两者之间的所有行
- #,/pat/:表示从第#行开始到pat匹配到的行为止,第#行以及pat匹配到的行以及之间的所有行
- 步进范围:
- 1~2:表示处理奇数行
- 2~2:表示处理偶数行
更多的地址范围,参见
man sed
的帮助手册的Addresses部分。 -
命令:用于处理输入行,对输入行执行的操作,常用的命令如下:
- p:打印当前模式空间的内容,并将其追加到标准输出流中
- Ip:忽略大小写输出
- d:删除模式空间中被处理的行,并立即开始下一轮的循环
- a [\]text:在指定行后面追加text指定的文本,并且支持使用\n实现换行从而实现多行追加
- i [\]text:在指定行前面插入text指定的文本
- c [\]text:将指定行替换为text指定的文本,text指定的文本既可以是单行,也可以是多行
- w file:将模式空间中的内容写入到file指定的文件中
- r file:将file指定的文件中的内容读取到模式空间中匹配的行后面
- =:将模式空间中的内容添加行号并打印到标准输出流中
- !:对模式空间中的匹配行进行取反处理
- s/pattern/string/修饰符:将pattern匹配到的内容替换为string指定的内容,这两者之间的分隔符可以指定为其他单字符,比如s@pattern@string@或者s#pattern#string#,唯一需要注意的是,表达式中的分隔符需要前后一致,不能写成s@pattern#string#这种前后不一致的情况。常用的修饰符有如下几种:
- g:行内全局搜索,即如果pattern可以在一行中进行多次匹配,那么所有这些匹配都会被替换为string指定的内容,如果不指定g,则默认是只处理第一次匹配
- p:显示被命令处理过的行,未被命令处理过的行则不会被打印到标准输出流中
- w /path/to/file:将被命令处理过的行写入到/path/to/file指定的文件中
- I,i:忽略大小写,即在pattern匹配的时候,不区分大小写
除了上述sed
在模式空间中的基础用法之外,还有高级用法,即将匹配的内容在模式空间(Pattern Space)与保持空间(Hold Space)之间进行相互转存,从而实现一些特定的操作。这里将会介绍常用的操作模式空间与保持空间内容切换的命令,常见命令如下所示:
- P:将模式空间中开头到\n之间的内容插入到标准输出流之前进行打印
- h:用模式空间中的内容覆盖保持空间中的内容
- H:将模式空间中的内容追加到保持空间中
- g:用保持空间中的内容覆盖模式空间中的内容
- G:将保持空间中的内容追加到模式空间中
- x:将模式空间中的内容与保持空间中的内容进行互换
- n:将匹配行的下一行读取并覆盖模式空间
- N:将匹配行的下一行读取并追加到模式空间
- d:删除模式空间中的行
- D:如果模式空间中包含换行符,则删除模式空间开头到第一个换行符之间的内容,并且不再读取新的输入行到模式空间中,而是使用此时模式空间的内容重新启动循环;如果模式空间中不包含换行符,此时效果等效于d命令,删除模式空间的内容,并且开始下一次匹配
更多的关于sed
的命令解释,参见man sed
的帮助手册的COMMAND SYNOPSIS部分的介绍。
3.2. bash变量内容替换、删除和替换
bash是支持变量内容替换的,虽然用的不多,但是在有些场景下,还是很好用的。可以通过参数扩展(Parameter Expansion)实现变量内容的删除、取代和替换等操作。
3.2.1. 变量内容的删除与替换
变量内容的删除可以分为从前往后删除,以及从后向前删除。前者用#号表示删除匹配到的最短的结果;##表示删除匹配到的最长的结果,这两个都代表从前向后删除。后者用%号表示从后向前删除匹配到的最短的结果;%%表示从后向前删除匹配到的最长的结果。
变量内容替换则使用/pattern/string表示将第一个被pattern匹配到的内容替换为string指定的内容;//pattern/string表示将变量内容中所有被pattern匹配到的内容都替换为string指定的内容。上述描述只作为表格如下所示:
动作及方向 | 变量内容操作形式 | 说明 |
---|---|---|
最短变量内容删除,从前向后 | ${var#pattern} | 将var变量中被pattern匹配到的最短内容部分删除 |
最长变量内容删除,从前向后 | ${var##pattern} | 将var变量中被pattern匹配到的最长内容部分删除 |
最短变量内容删除,从后向前 | ${var%pattern} | 将var变量中被pattern匹配到的最短内容部分删除 |
最长变量内容删除,从后向前 | ${var%%pattern} | 将var变量中被pattern匹配到的最长内容部分删除 |
变量内容替换,仅第一个 | ${var/pattern/string} | 将var变量中被pattern匹配到的第一个内容替换为string指定的内容 |
变量内容替换,全部 | ${var//pattern/string} | 将var变量中被pattern匹配到的全部内容都替换为string指定的内容 |
具体示例参见下一部分的第三块内容
3.2.2. 变量测试与内容设置
可以根据被判断变量str以及表达式expr的值是否设置以及是否为空来决定最终var变量的内容。具体如下表所示:
变量内容操作形式 | 变量str未设置时 | 变量str为空字符串时 | 变量str设置为非空字符串时 |
---|---|---|---|
var=${str-expr} | var=expr | var=,即也为空字符串 | var=$str |
var=${str:-expr} | var=expr | var=expr | var=$str |
var=${str+expr} | var=,即为空字符串 | var=expr | var=expr |
var=${str:+expr} | var=,即为空字符串 | var=,即为空字符串 | var=expr |
var=${str=expr} | str=expr; var=expr | str保持不变;var=,即为空字符串 | str保持不变;var=$str |
var=${str:=expr} | str=expr; var=expr | str=expr; var=expr | str保持不变;var=$str |
var=${str?expr} | expr打印到标准错误输出 | var=,即为空字符串 | var=$str |
var=${str:?expr} | expr打印到标准错误输出 | expr打印到标准错误输出 | var=$str |
关于这部分的更详细的解释,参见man bash
的Parameter Expansion部分的介绍。
3.3. sed命令以及变量内容删除应用示例
-
利用sed 取出ifconfig命令中本机的IPv4地址
[root@c7u6m1 yum.repos.d]# ifconfig eth0 | sed -n -re 's/^[^0-9]+([0-9.]{7,15}) {1,}netmask.*/\1/p' 192.168.122.2 [root@c7u6m1 yum.repos.d]#
如果不加
-r
选项,则是无法使用上述的正则表达式的。-r, --regexp-extended
:在脚本中使用拓展正则表达式。 -
删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符
fstab文件的原始内容:
[root@c7u6m1 tmp]# cat fstab # # /etc/fstab # Created by anaconda on Mon Dec 7 14:06:24 2020 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/vg0-root / xfs defaults 0 0 UUID=955884ac-e63e-46b1-a192-d97bef64ada9 /boot xfs defaults 0 0 UUID=257a8710-f5e9-44e4-a933-f9f6fcd0d1a3 swap swap defaults 0 0
使用
sed
命令删除#号开头且其后跟一个或者多个空白符的行开头的#号和空白符,具体如下所示:[root@c7u6m1 tmp]# sed -n -re ':L;s/^# {1,}([^[:blank:]]+)/\1/;H;t L;p' fstab # /etc/fstab Created by anaconda on Mon Dec 7 14:06:24 2020 # Accessible filesystems, by reference, are maintained under '/dev/disk' See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/vg0-root / xfs defaults 0 0 UUID=955884ac-e63e-46b1-a192-d97bef64ada9 /boot xfs defaults 0 0 UUID=257a8710-f5e9-44e4-a933-f9f6fcd0d1a3 swap swap defaults 0 0 [root@c7u6m1 tmp]#
上述通过借助保持空间将处理的文件内容加入到保持空间中,然后通过标签label实现循环匹配处理,从而达到删除#号加多个空格开头的行中的#号以及空格的目的。
-
处理/etc/fstab路径,使用sed命令取出其目录名和基名
此处使用变量删除和
sed
两种方式来实现。-
提取出目录名称,具体如下所示:
[root@c7u6m1 tmp]# var=/etc/fstab [root@c7u6m1 tmp]# echo "${var%/*}" /etc [root@c7u6m1 tmp]# echo "${var%/*}/" /etc/ [root@c7u6m1 tmp]#
上述就提取除了给定文件路径的目录名称部分,而不包含完整路径中的文件名。
除了用上述的变量删除的方式进行目录名称的提取之外,用
sed
命令方式进行提取,结果如下:[root@c7u6m1 tmp]# echo '/etc/fstab' | sed -n -re 's/(^\/.*\/)[^[:blank:]]+/\1/p' /etc/ [root@c7u6m1 tmp]#
上述即为通过变量名和
sed
命令进行给定绝对路径文件中的目录名称提取的两种方式,当然,系统内建了dirname
这个命令可以用于实现上述效果,具体如下:[root@c7u6m1 tmp]# dirname '/etc/fstab' /etc [root@c7u6m1 tmp]#
上述的方式很简答, 无需像上述两种方式那样需要写那么多字符才能实现。
-
提取出文件名称,具体如下所示:
[root@c7u6m1 tmp]# var=/etc/fstab [root@c7u6m1 tmp]# echo "${var#/*/}" fstab
上述就是用变量删除提取出了完整路径中的文件名部分,而不包含路径名称信息。
除了使用上述的变量删除的方式进行路径中的文件名提取之外,使用
sed
命令提取文件名的方式如下:[root@c7u6m1 tmp]# echo '/etc/fstab' | sed -n -re 's/^\/[^[:blank:]]+\/([^\/]+)/\1/p' fstab [root@c7u6m1 tmp]#
上述就是通过变量删除以及
sed
命令的方式实现的给定绝对路径文件中的文件名提取的两种方式。当然,除了上述两种复杂的实现方式之外,系统其实内建了一个命令用于实现上述目的,即basename
。其结果如下所示:[root@c7u6m1 tmp]# basename '/etc/fstab' fstab [root@c7u6m1 tmp]#
使用系统内建命令实现的效果简单粗暴、有效。
-