Shell编程

1.crontab定时任务

        1、crontab -l 查看定时任务列表

        2、crontab -e 编辑定时任务

        3、service crond stop 关闭定时任务

2. $

  • $0 :Shell 的命令本身
  • $1-9 :表示 Shell 的第几个参数
  • $? :显示最后命令的执行情况
  • $# :传递到脚本的参数个数
  • $$ :脚本运行的当前进程 ID 号
  • $* :以一个单字符串显示所有向脚本传递的参数
  • $! :后台运行的最后一个进程的 ID 号
  • $- :显示 Shell 使用的当前选项
  • $(命令) :执行并获取命令输出

2.1 引用变量用法

  • 直接引用

    [root@localhost testShell]# x=1024
    [root@localhost testShell]# echo $x
    x
    
  • 利用双引号

    [root@localhost testShell]# x=1024
    [root@localhost testShell]# echo "x=$x"
    x=1024
    
  • 使用 ${ } 作为单词边界

    [root@localhost testShell]# x=1024
    [root@localhost testShell]# echo "x=${x}-123"
    x=1024-123
    
  • 使用 ${#} 获取变量字符串长度

    [root@localhost testShell]# x=1024
    [root@localhost testShell]# echo "length=${#x}"
    length=4

2.2 引用脚本或函数参数

  • 1 表示 Shell 脚本文件名,n 从 2 开始表示第 n 个参数,第 2 个参数是 $2

    [root@localhost testShell]# echo 'echo $1 $2 $3' > hello.sh
    [root@localhost testShell]# cat hello.sh 
    echo $1 $2 $3
    [root@localhost testShell]# sh hello.sh 1 2 3
    1 2 3
    
  • 使用 $# 获取脚本或函数参数的个数

    [root@localhost testShell]# echo 'echo $#' > hello.sh
    [root@localhost testShell]# cat hello.sh 
    echo $#
    [root@localhost testShell]# sh hello.sh 1 2 3 4 5 6 
    6
    

2.3 上条命令的返回值

使用 $? 上条命令的返回值。

0:表示没有错误,其他任何数值:表示有错误。

[root@localhost testShell]# echo 111 > 1.sh
[root@localhost testShell]# rm 2.sh
rm: cannot remove ‘2.sh’: No such file or directory
[root@localhost testShell]# echo $?
1
[root@localhost testShell]# rm 1.sh 
rm: remove regular file ‘1.sh’? y
[root@localhost testShell]# echo $?
0

2.4 执行并获取命令输出

[root@localhost testShell]# echo $(date)
Tue Aug 17 06:50:29 EDT 2021

2.5 获取当前进程 ID

[root@localhost testShell]# echo $$
80329

2.6 获取后台运行的最后一个进程 ID

[root@localhost testShell]# echo 'ping www.baidu.com' > ping.sh
[root@localhost testShell]# tail -f ping.sh &
[1] 88991
[root@localhost testShell]# echo $!
88991
[root@localhost testShell]# kill $!
[root@localhost testShell]# echo $!
88991
[1]+  Terminated              tail -f ping.sh

2.7 获取 Shell 选项

[root@localhost testShell]# echo $-
himBH

3. ``

被`包含的内容会直接执行

4. 去掉字符串最外面双引号

echo "内容" | sed 's/\"//g'

5. debug模式

set -x

6. 字符替换

/要替换的字符串(只找第一个)/替换成的字符串
//要替换的字符串(全部替换)/替换成的字符串

[root@localhost testShell]# url=www.baiud.com
[root@localhost testShell]# echo ${net/baidu/google}
www.google.com
[root@localhost testShell]# echo ${net//./-}
www-baidu-com
[root@localhost testShell]# echo ${net/./-}
www-baidu.com

7. 字符串截取

#查找的字符串
%查找的字符串

[root@localhost testShell]# url=www.baiud.com
[root@localhost testShell]# echo ${url#*www.}
baidu.com
[root@localhost testShell]# echo ${url%*.com}
www.baidu

8. =赋值的时候,两边不能出空格,不然会被认为是命令

二、grep 命令

作用

Grep 筛选器在文件中搜索特定的字符模式,并显示包含该模式的所有行。在文件中搜索的模式称为 正则表达式. (grep 代表正则表达式的全局搜索和打印输出)。

语法

grep -options(参数) pattern(关键词) files(文本文件)

主要参数

-c :只输出匹配模式的行数
-h :只显示匹配的行,不显示文件名。
-i :忽略匹配时的大小写。
-l :只显示文件名列表。
-n :显示匹配的行及其行号
-r :显示文件所在目录即路径。
-v :输出所有不匹配的行。
-e exp : 指定该选项的表达式,可以多次使用。
-f file :指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
-E :将样式为延伸的正则表达式来使用。
-w :匹配整个单词。
-r :明确要求搜索子目录。
-d skip :忽略子目录。
-o :只打印匹配行的匹配部分,每个这样的部分在单独的输出行上。
\ :忽略正则表达式中特殊字符的原有含义。
[ ]:单个字符,如[A]即A符合要求。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求。
.:所有的单个字符。
*:所有字符,长度可以为0。

-A n : 除了显示符合范本样式的那一行之外,并显示该行之后n
-B n : 除了显示符合范本样式的那一行之外,并显示该行之前n
-C n : 除了显示符合范本样式的那一行之外,并显示该行之前以及之后n

示例命令

  1. 考虑下面的文件作为输入,键入cat > geekfile.txt 后回车;
$ cat > geekfile.txt
  1. 输入如下内容并键入回车;
unix is great os. unix is opensource. unix is free os.
learn operating system.
Linux is a family of open-source Unix-like operating systems based on the Linux kernel.
Unix linux which one you choose.
uNix is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful.
  1. 在键盘上按下Ctrl+D (或者键入Control-D),保存文本并回到shell提示符。

1、 -i 忽略匹配时的大小写:选项允许在被检索文件中不敏感地搜索字符串大小写。它匹配“UNIX”、“Unix”、“unix”等单词。

$ grep -i "UNix" geekfile.txt

输出:
在这里插入图片描述
2、-c只输出匹配模式的行数: 我们可以找到与给定字符串模式匹配的行数。

$ grep -c "unix" geekfile.txt

输出:
在这里插入图片描述
3、-l显示与模式匹配的文件名: 我们可以只显示包含给定字符串模式的文件。

$ grep -l "unix" *
or
$ grep -l "unix" geekfile.txt f1.txt f2.txt f3.txt

输出:
在这里插入图片描述
在这里插入图片描述
4、-w匹配文件中的整个单词: 默认情况下,grep 匹配给定的字符串/模式,即使它在文件中作为子字符串出现。Grep 的-w选项使它只匹配整个单词。

$ grep -w "unix" geekfile.txt

输出:
在这里插入图片描述
5、-o只打印匹配行的匹配部分: 默认情况下,grep 显示具有匹配字符串的整个行。我们可以使用-o 选项使 grep 只显示匹配的字符串。

$ grep -o "unix" geekfile.txt

输出:
在这里插入图片描述
6、grep -n 输出时显示行号: 显示匹配行的文件及行号。

$ grep -n "unix" geekfile.txt

输出:
在这里插入图片描述
7、-v 反转模式匹配: 可以使用-v 选项显示与指定搜索模式不匹配的行。

$ grep -v "unix" geekfile.txt

输出:
在这里插入图片描述
8、^ 匹配以字符串开头的行: ^ 正则表达式模式指定行的开头。可以在 grep 中使用它来匹配以给定字符串或模式开头的行。

$ grep "^unix" geekfile.txt

输出:
在这里插入图片描述
9、$匹配以字符串结尾的行: $正则表达式模式指定行的结尾。可以在 grep 中使用它来匹配以给定字符串或模式结尾的行。

$ grep "os.$" geekfile.txt

输出:
在这里插入图片描述
10、-e 指定该选项的表达式,可以多次使用:

$ grep –e "unix" –e "linux" –e "open-source" geekfile.txt

输出:
在这里插入图片描述
11、 -f file 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。

$ cat > pattern.txt
Agarwal
Aggarwal
Agrawal
$ grep –f pattern.txt  geekfile.txt
$ grep -f pattern.txt  geekfile.txt noSuchFile.txt

输出:
在这里插入图片描述
12、从一个文件中打印 n 行: -A 在 结果后 打印搜索行和 n 行, -B 在 结果前 打印搜索行和 n 行, -C 在 结果前后 打印搜索行和 n 行。

  1. 语法:
$ grep -A[NumberOfLines(n)] [search] [file]  
$ grep -B[NumberOfLines(n)] [search] [file]  
$ grep -C[NumberOfLines(n)] [search] [file]  
  1. 例子:
$ grep -A1 learn geekfile.txt
  1. 输出:
    在这里插入图片描述

13、-r 查找文件所在 目录 即路径:

$ grep –r "linux" ./

输出:
在这里插入图片描述

三、awk命令

前言

awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。

awk命令格式

awk [options] 'script' var=value file(s) 
awk [options] -f scriptfile var=value file(s) 

    -F fs fs指定输入分隔符,fs可以是字符串或正则表达式
    -v var=value 赋值一个用户定义变量,将外部变量传递给awk
    -f scriptfile 从脚本文件中读取awk命令

其中script格式:awk脚本是由模式和操作组成的。

awk脚本

模式

操作

正则表达式

关系表达式

模式匹配表达式

BEGIN语句块,pattern语句块,END语句块

一个或多个命令,函数,表达式组成

  • 模式,模式可以是以下任意一种:

    正则表达式:使用通配符的扩展集
    关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试
    模式匹配表达式:用运算符~匹配和~!不匹配
    BEGIN语句块,pattern语句块,END语句块
    
  • 操作

    操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大刮号内,
    主要部分是:变量或数组赋值、输出命令、内置函数、控制流语句。
    

awk脚本基本格式

awk 'BEGIN{ commands } pattern{ commands } END{ commands }' file 

// 一个awk脚本通常由BEGIN,通用语句块,END语句块组成,三部分都是可选的。 
// 脚本通常是被单引号或双引号包住。
awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename
awk "BEGIN{ i=0 } { i++ } END{ print i }" filename

awk执行过程分析

第一步: 执行BEGIN { commands } pattern 语句块中的语句

  • BEGIN语句块:在awk开始从输入输出流中读取行之前执行,在BEGIN语句块中执行如变量初始化,打印输出表头等操作。

第二步:从文件或标准输入中读取一行,然后执行pattern{ commands }语句块。它逐行扫描文件,从第一行到最后一行重复这个过程,直到全部文件都被读取完毕。

  • pattern语句块:pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行。{ }类似一个循环体,会对文件中的每一行进行迭代,通常将变量初始化语句放在BEGIN语句块中,将打印结果等语句放在END语句块中。

第三步:当读至输入流末尾时,执行END { command }语句块

  • END语句块:在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。

awk内置变量

$n : 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。
$0 : 这个变量包含执行过程中当前行的文本内容。
ARGC : 命令行参数的数目。
ARGIND : 命令行中当前文件的位置(从0开始算)。
ARGV : 包含命令行参数的数组。
CONVFMT : 数字转换格式(默认值为%.6g)。
ENVIRON : 环境变量关联数组。
ERRNO : 最后一个系统错误的描述。
FIELDWIDTHS : 字段宽度列表(用空格键分隔)。
FILENAME : 当前输入文件的名。
NR : 表示记录数,在执行过程中对应于当前的行号
FNR : 同NR :,但相对于当前文件。
FS : 字段分隔符(默认是任何空格)。
IGNORECASE : 如果为真,则进行忽略大小写的匹配。
NF : 表示字段数,在执行过程中对应于当前的字段数。 print $NF答应一行中最后一个字段
OFMT : 数字的输出格式(默认值是%.6g)。
OFS : 输出字段分隔符(默认值是一个空格)。
ORS : 输出记录分隔符(默认值是一个换行符)。
RS : 记录分隔符(默认是一个换行符)。
RSTART : 由match函数所匹配的字符串的第一个位置。
RLENGTH : 由match函数所匹配的字符串的长度。
SUBSEP : 数组下标分隔符(默认值是34)。    

将外部变量值传递给awk

  • 借助 -v 选项,可以将来自外部值(非stdin)传递给awk
VAR=10000
echo | awk -v VARIABLE=$VAR '{ print VARIABLE }'
  • 定义内部变量接收外部变量
var1="aaa"
var2="bbb"
echo | awk '{ print v1,v2 }' v1=$var1 v2=$var2
  • 当输入来自文件时
 awk '{ print v1,v2 }' v1=$var1 v2=$var2 filename

awk运算

  • 算术运算:(+,-,*,/,&,!,……,++,–)

所有用作算术运算符进行操作时,操作数自动转为数值,所有非数值都变为0

  • 赋值运算:(=, +=, -=,*=,/=,%=,……=,**=)
  • 逻辑运算符: (||, &&)
  • 关系运算符:(<, <=, >,>=,!=, ==)
  • 正则运算符:(~,~!)(匹配正则表达式,与不匹配正则表达式)
awk 'BEGIN{a="100testa";if(a ~ /^100*/){print "ok";}}'
ok

awk高级输入输出

读取下一条记录:next 语句

awk中next语句使用:在循环逐行匹配,如果遇到next,就会跳过当前行,直接忽略下面语句。而进行下一行匹配。net语句一般用于多行合并:

awk 'NR%2==1{next}{print NR,$0;}' text.txt
// 说明:当记录行号除以2余1,就跳过当前行。
// 下面的print NR,$0也不会执行。
// 下一行开始,程序有开始判断NR%2值。
// 这个时候记录行号是2,就会执行下面语句块print NR,$0;

读取一行记录:getline 语句

awk getline用法:输出重定向需用到getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内容,并给NF,NR和FNR等内建变量赋值。如果得到一条记录,getline函数返回1,如果到达文件的末尾就返回0,如果出现错误,例如打开文件失败,就返回-1。

语法格式:getline var 变量var包含了特定行的内容

用法说明:

  • 当其左右无重定向符时|,<时:getline作用于当前文件,读入当前文件的第一行给其后跟的变量var或$0(无变量),应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。
  • 当其左右有重定向符时|,<时:getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。

文件操作

  • 打开文件 open(“filename”)
  • 关闭文件 close(“filename”)
  • 输出到文件 重定向到文件,如echo | awk ‘{printf(“hello word!n”) > “datafile”}’

循环结构

for循环

for(变量 in 数组)  
{语句} 
     
for(变量;条件;表达式) 
{语句} 

while循环

while(表达式) 
    {语句} 

do…while循环

do  
{语句} while(条件) 

其他相关语句

break:退出程序循环
continue: 进入下一次循环
next:读取下一个输入行
exit:退出主输入循环,进入END,若没有END或END中有exit语句,则退出脚本。

数组等

具体请看博主讲解,引用:https://www.cnblogs.com/quincyhu/p/5884390.html

awk实例

print & $0

// print是awk打印指定内容的主要命令
$ awk '{print}' /etc/passwd == awk '{print $0}' /etc/passwd  

//不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本
$ awk '{print " "}' /etc/passwd                                       

//输出相同个数的a行,一行只有一个a字母
$ awk '{print "a"}' /etc/passwd                                        

$ awk -F":" '{print $1}' /etc/passwd 
//将每一行的前二个字段,分行输出,进一步理解一行一行处理文本
$ awk -F: '{print $1; print $2}' /etc/passwd    

//输出字段1,3,6,以制表符作为分隔符
$ awk  -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd        

-f指定脚本文件

//效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定
$ awk -f script.awk  file
    BEGIN{
    FS=":"
    }
    {print $1}               
 

$ awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test 
I find 4 blank lines.

//计算文件大小
$ ls -l | awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}'  total size is 17487

-F指定分隔符

// $1 指指定分隔符后,第一个字段,$3第三个字段, \t是制表符
// 一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格
$ awk -F":" '{print $1}'  /etc/passwd

// $1与$3相连输出,不分隔
$ awk -F":" '{print $1 $3}'  /etc/passwd  

// 多了一个逗号,$1与$3使用空格分隔
$ awk -F":" '{print $1,$3}'  /etc/passwd   

// $1与$3之间手动添加空格分隔
$ awk -F":" '{print $1 " " $3}'  /etc/passwd         

// 自定义输出
$ awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd 

// 显示每行有多少字段
$ awk -F: '{print NF}' /etc/passwd 

// 将每行第NF个字段的值打印出来
$ awk -F: '{print $NF}' /etc/passwd   

//显示只有4个字段的行
$ awk -F: 'NF==4 {print }' /etc/passwd 

//显示每行字段数量大于2的行
$ awk -F: 'NF>2{print $0}' /etc/passwd  

//输出每行的行号
$ awk '{print NR,$0}' /etc/passwd      

//依次打印行号,字段数,最后字段值,制表符,每行内容
$ awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd 

//显示第5行
$ awk -F: 'NR==5{print}'  /etc/passwd  

//显示第5行和第6行
$ awk -F: 'NR==5 || NR==6{print}'  /etc/passwd    

//不显示第一行
$ route -n|awk 'NR!=1{print}'                                       

    四、sed命令

        sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

[root@www ~]# sed [-nefr] [动作]
选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。

动作说明: [n1[,n2]]function
n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』

function:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

以行为单位的新增/删除


将 /etc/passwd 的内容列出并且列印行号,同时,请将第 2~5 行删除!

[root@www ~]# nl /etc/passwd | sed '2,5d'
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
.....(后面省略).....
sed 的动作为 '2,5d' ,那个 d 就是删除!因为 2-5 行给他删除了,所以显示的数据就没有 2-5 行罗~ 另外,注意一下,原本应该是要下达 sed -e 才对,没有 -e 也行啦!同时也要注意的是, sed 后面接的动作,请务必以 '' 两个单引号括住喔!

只要删除第 2 行

nl /etc/passwd | sed '2d' 

要删除第 3 到最后一行

 nl /etc/passwd | sed '3,$d' 

在第二行后(亦即是加在第三行)加上『drink tea?』字样!

[root@www ~]# nl /etc/passwd | sed '2a drink tea'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
drink tea
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
.....(后面省略).....

那如果是要在第二行前

 nl /etc/passwd | sed '2i drink tea' 

如果是要增加两行以上,在第二行后面加入两行字,例如『Drink tea or .....』与『drink beer?』

[root@www ~]# nl /etc/passwd | sed '2a Drink tea or ......\
> drink beer ?'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ......
drink beer ?
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
.....(后面省略).....

每一行之间都必须要以反斜杠『 \ 』来进行新行的添加喔!所以,上面的例子中,我们可以发现在第一行的最后面就有 \ 存在。


以行为单位的替换与显示


将第2-5行的内容取代成为『No 2-5 number』呢?

[root@www ~]# nl /etc/passwd | sed '2,5c No 2-5 number'
1 root:x:0:0:root:/root:/bin/bash
No 2-5 number
6 sync:x:5:0:sync:/sbin:/bin/sync
.....(后面省略)....
透过这个方法我们就能够将数据整行取代了!

仅列出 /etc/passwd 文件内的第 5-7 行

[root@www ~]# nl /etc/passwd | sed -n '5,7p'
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

可以透过这个 sed 的以行为单位的显示功能, 就能够将某一个文件内的某些行号选择出来显示。

数据的搜寻并显示

搜索 /etc/passwd有root关键字的行

nl /etc/passwd | sed '/root/p'
1  root:x:0:0:root:/root:/bin/bash
1  root:x:0:0:root:/root:/bin/bash
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
3  bin:x:2:2:bin:/bin:/bin/sh
4  sys:x:3:3:sys:/dev:/bin/sh
5  sync:x:4:65534:sync:/bin:/bin/sync
....下面忽略 

如果root找到,除了输出所有行,还会输出匹配行。

使用-n的时候将只打印包含模板的行。

nl /etc/passwd | sed -n '/root/p'
1  root:x:0:0:root:/root:/bin/bash

数据的搜寻并删除

删除/etc/passwd所有包含root的行,其他行输出

nl /etc/passwd | sed  '/root/d'
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh
3  bin:x:2:2:bin:/bin:/bin/sh
....下面忽略
#第一行的匹配root已经删除了

数据的搜寻并执行命令

找到匹配模式eastern的行后,

搜索/etc/passwd,找到root对应的行,执行后面花括号中的一组命令,每个命令之间用分号分隔,这里把bash替换为blueshell,再输出这行:

 nl /etc/passwd | sed -n '/root/{s/bash/blueshell/;p}'
 1  root:x:0:0:root:/root:/bin/blueshell

如果只替换/etc/passwd的第一个bash关键字为blueshell,就退出

nl /etc/passwd | sed -n '/bash/{s/bash/blueshell/;p;q}'    
1  root:x:0:0:root:/root:/bin/blueshell

最后的q是退出。

其中,加了g(GLOBAL)是全部替换,不加g 是只替换第一次出现的字符

数据的搜寻并替换

除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的搜寻并取代。基本上 sed 的搜寻与替代的与 vi 相当的类似!他有点像这样:

sed 's/要被取代的字串/新的字串/g'

先观察原始信息,利用 /sbin/ifconfig 查询 IP

[root@www ~]# /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:90:CC:A6:34:84
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::290:ccff:fea6:3484/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
.....(以下省略).....
本机的ip是192.168.1.100。

将 IP 前面的部分予以删除

[root@www ~]# /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g'
192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0

接下来则是删除后续的部分,亦即: 192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
 

将 IP 后面的部分予以删除

[root@www ~]# /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g'
192.168.1.100

多点编辑

一条sed命令,删除/etc/passwd第三行到末尾的数据,并把bash替换为blueshell

nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'
1  root:x:0:0:root:/root:/bin/blueshell
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh

-e表示多点编辑,第一个编辑命令删除/etc/passwd第三行到末尾的数据,第二条命令搜索bash替换为blueshell。

直接修改文件内容(危险动作)


sed 可以直接修改文件的内容,不必使用管道命令或数据流重导向! 不过,由於这个动作会直接修改到原始的文件,所以请你千万不要随便拿系统配置来测试! 我们还是使用下载的 regular_express.txt 文件来测试看看吧!

利用 sed 将 regular_express.txt 内每一行结尾若为 . 则换成 !

[root@www ~]# sed -i 's/\.$/\!/g' regular_express.txt

利用 sed 直接在 regular_express.txt 最后一行加入『# This is a test』

[root@www ~]# sed -i '$a # This is a test' regular_express.txt

由於 $ 代表的是最后一行,而 a 的动作是新增,因此该文件最后新增『# This is a test』!

sed 的『 -i 』选项可以直接修改文件内容,这功能非常有帮助!举例来说,如果你有一个 100 万行的文件,你要在第 100 行加某些文字,此时使用 vim 可能会疯掉!因为文件太大了!那怎办?就利用 sed 啊!透过 sed 直接修改/取代的功能,你甚至不需要使用 vim 去修订!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

-DCCC-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值