Shell脚本学习笔记(从入门到精通)

第1章 Shell概述

大数据程序员为什么要学习Shell呢?

1)需要看懂运维人员编写的Shell程序。

2)偶尔会编写一些简单Shell程序来管理集群、提高开发效率。
在这里插入图片描述

第2章 Shell解析器

(1)Linux提供的Shell解析器有:

[root@master ~]$ cat /etc/shells 
/bin/sh #是bash的一个快捷方式 
/bin/bash #bash是大多数Linux默认的shell,包含的功能几乎可以涵盖shell所有的功能 
/sbin/nologin #表示非交互,不能登录操作系统 
/bin/dash #小巧,高效,功能相比少一些 
/bin/csh #具有C语言风格的一种shell,具有许多特性,但也有一些缺陷
/bin/tcsh #是csh的增强版,完全兼容csh

(2)bash和sh的关系

[root@master bin]$ ll | grep bash
-rwxr-xr-x. 1 root root 941880 511 2016 bash
lrwxrwxrwx. 1 root root      4 527 2017 sh -> bash

(3)Centos默认的解析器是bash

[root@master bin]$ echo $SHELL
/bin/bash

第3章 Shell脚本入门

1)脚本格式

脚本以#!/bin/bash开头(指定解析器)

2)第一个Shell脚本:helloworld

(1)需求:创建一个Shell脚本,输出helloworld

(2)案例实操:

[root@master datas]$ touch helloworld.sh
[root@master datas]$ vi helloworld.sh

在helloworld.sh中输入如下内容

#!/bin/bash
echo "helloworld"

(3)脚本的常用执行方式

第一种:采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)

  • sh+脚本的相对路径

    [root@master datas]$ sh helloworld.sh 
    Helloworld
    
  • sh+脚本的绝对路径

    [root@master datas]$ sh /home/atguigu/datas/helloworld.sh 
    helloworld
    
  • bash+脚本的相对路径

    [root@master datas]$ bash helloworld.sh 
    Helloworld
    
  • bash+脚本的绝对路径

    [root@master datas]$ bash /home/atguigu/datas/helloworld.sh 
    Helloworld
    

第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)

(a)首先要赋予helloworld.sh 脚本的+x权限

[root@master datas]$ chmod 777 helloworld.sh

(b)执行脚本

  • 相对路径(推荐使用)

    [root@master datas]$ ./helloworld.sh 
    Helloworld
    
  • 绝对路径

    [root@master datas]$ /home/atguigu/datas/helloworld.sh 
    Helloworld
    

注意:第一种执行方法,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限

3)第二个Shell脚本:多命令处理

(1)需求: 在/home/atguigu/目录下创建一个cls.txt,在cls.txt文件中增加“I love cls”。

(2)案例实操:

[root@master datas]$ touch batch.sh
[root@master datas]$ vi batch.sh

在batch.sh中输入如下内容

#!/bin/bash

cd /home/atguigu
touch cls.txt
echo "I love cls" >>cls.txt

第4章 Shell中的变量

4.1 系统变量

1)常用系统变量

H O M E 、 HOME、 HOMEPWD、 S H E L L 、 SHELL、 SHELLUSER等

2)案例实操

(1)查看系统变量的值

[root@master datas]$ echo $HOME
/home/atguigu

(2)显示当前Shell中所有变量:set

[root@master datas]$ set
BASH=/bin/bash
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()

4.2 自定义变量

1.基本语法

(1)定义变量:变量=值

(2)撤销变量:unset 变量

(3)声明静态变量:readonly 变量,注意:不能unset

2.变量定义规则

(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写

(2)等号两侧不能有空格!

(3)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。

(4)变量的值如果有空格,需要使用双引号或单引号括起来。

3.案例实操

(1)定义变量A

[root@master datas]$ A=5
[root@master datas]$ echo $A
5

(2)给变量A重新赋值

[root@master datas]$ A=8
[root@master datas]$ echo $A
8

(3)撤销变量A

[root@master datas]$ unset A
[root@master datas]$ echo $A

(4)声明静态的变量B=2,不能unset(重启自动消失)

[root@master datas]$ readonly B=2
[root@master datas]$ echo $B
2
[root@master datas]$ B=9
-bash: B: readonly variable

(5)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算

[root@master ~]$ C=1+2
[root@master ~]$ echo $C
1+2

(6)变量的值如果有空格,需要使用双引号或单引号括起来

[root@master ~]$ D=I love banzhang
-bash: world: command not found
[root@master ~]$ D="I love banzhang"
[root@master ~]$ echo $D
I love banzhang

(7)可把变量提升为全局环境变量,可供其他Shell程序使用

格式:export 变量名

[root@master datas]$ vim helloworld.sh 

在helloworld.sh文件中增加echo $B

#!/bin/bash

echo "helloworld"
echo $B
[root@master datas]$ ./helloworld.sh 
Helloworld

发现并没有打印输出变量B的值。

[root@master datas]$ export B
[root@master datas]$ ./helloworld.sh 
helloworld
2

4.3 特殊变量:$n

1.基本语法

$n(功能描述:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}

2.案例实操

(1)输出该脚本文件名称、输入参数1和输入参数2 的值

[root@master datas]$ touch parameter.sh 
[root@master datas]$ vim parameter.sh

#!/bin/bash
echo "$0  $1  $2"

[root@master datas]$ chmod 777 parameter.sh

[root@master datas]$ ./parameter.sh 1 2
parameter.sh  1 2

4.4 特殊变量:$#

1.基本语法

$# (功能描述:获取所有输入参数个数,常用于循环)。

2.案例实操

(1)获取输入参数的个数

[root@master datas]$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"
echo $#

[root@master datas]$ chmod 777 parameter.sh

[root@master datas]$ ./parameter.sh cls  xz
parameter.sh cls xz 
2

4.5 特殊变量:$*、$@

1.基本语法

$* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
$@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)

2.案例实操

(1)打印输入的所有参数

[root@master datas]$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"
echo $#
echo $*
echo $@

[root@master datas]$ bash parameter.sh 1 2 3
parameter.sh  1   2
3
1 2 3
1 2 3

4.6 特殊变量:$?

1.基本语法

$? (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。)

2.案例实操

(1)判断helloworld.sh脚本是否正确执行

[root@master datas]$ ./helloworld.sh 
hello world
[root@master datas]$ echo $?
0

第5章 运算符

1.基本语法

(1)“$((运算式))”或“$[运算式]

(2)expr + , - , *, /, % 加,减,乘,除,取余

注意:expr运算符间要有空格

2.案例实操:

(1)计算3+2的值

[root@master datas]$ expr 2 + 3
5

(2)计算3-2的值

[root@master datas]$ expr 3 - 2 
1

(3)计算(2+3)X 4的值

  • (a)expr一步完成计算

    [root@master datas]$ expr `expr 2 + 3` \* 4 #这个小·是tab上面那个键,不是单引号
    20
    
  • (b)采用$[运算式]方式

    [root@master datas]$ S=$[(2+3)*4]
    [root@master datas]$ echo $S
    20
    

第6章 条件判断

1.基本语法

[ condition ]`注意condition前后要有空格`

注意:条件非空即为true,[ atguigu ]返回true,[] 返回false。

2.常用判断条件

(1)两个整数之间比较

  • = 字符串比较

  • -lt 小于(less than)

  • -le 小于等于(less equal)

  • -eq 等于(equal)

  • -gt 大于(greater than)

  • -ge 大于等于(greater equal)

  • -ne 不等于(Not equal)

(2)按照文件权限进行判断

  • -r 有读的权限(read)

  • -w 有写的权限(write)

  • -x 有执行的权限(execute)

(3)按照文件类型进行判断

  • -f 文件存在并且是一个常规的文件(file)

  • -e 文件存在(existence)

  • -d 文件存在并是一个目录(directory)

3.案例实操

(1)23是否大于等于22

[root@master datas]$ [ 23 -ge 22 ]
[root@master datas]$ echo $?
0

(2)helloworld.sh是否具有写权限

[root@master datas]$ [ -w helloworld.sh ]
[root@master datas]$ echo $?
0

(3)/home/atguigu/cls.txt目录中的文件是否存在

[root@master datas]$ [ -e /home/atguigu/cls.txt ]
[root@master datas]$ echo $?
1

(4)多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)

[root@master datas]$ [ condition ] && echo OK || echo notok
OK
[root@master datas]$ [ condition ] && [ ] || echo notok
notok

第7章 流程控制(重点)

7.1 if 判断

1.基本语法

if [ 条件判断式 ];then 
  程序 
fi 

或者

if [ 条件判断式 ] 
  then 
    程序 
fi

注意事项

  • [ 条件判断式 ],中括号和条件判断式之间必须有空格
  • if 后要有空格

2.案例实操

(1)输入一个数字,如果是1,则输出banzhang zhen shuai,如果是2,则输出cls zhen mei,如果是其它,什么也不输出。

[root@master datas]$ touch if.sh
[root@master datas]$ vim if.sh

#!/bin/bash

if [ $1 -eq "1" ]
then
        echo "banzhang zhen shuai"
elif [ $1 -eq "2" ]
then
        echo "cls zhen mei"
fi

[root@master datas]$ chmod 777 if.sh 
[root@master datas]$ ./if.sh 1
banzhang zhen shuai

7.2 case 语句

1.基本语法

case $变量名 in 
  "值1") 
    如果变量的值等于值1,则执行程序1 
    ;; 
  "值2") 
    如果变量的值等于值2,则执行程序2 
    ;; 
  …省略其他分支… 
  *) 
    如果变量的值都不是以上的值,则执行此程序 
    ;; 
esac

注意事项

  • case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
  • 双分号“;;”表示命令序列结束,相当于java中的break。
  • 最后的“*)”表示默认模式,相当于java中的default。

2.案例实操

(1)输入一个数字,如果是1,则输出banzhang,如果是2,则输出cls,如果是其它,输出renyao。

[root@master datas]$ touch case.sh
[root@master datas]$ vim case.sh

!/bin/bash

case $1 in
"1")
        echo "banzhang"
;;

"2")
        echo "cls"
;;

*)
        echo "renyao"
;;
esac

[root@master datas]$ chmod 777 case.sh
[root@master datas]$ ./case.sh 1
banzhang

7.3 for 循环

1.基本语法1

for (( 初始值;循环控制条件;变量变化 )) 
  do 
    程序 
  done

2.案例实操

(1)从1加到100

[root@master datas]$ touch for1.sh
[root@master datas]$ vim for1.sh

#!/bin/bash

s=0
for((i=0;i<=100;i++))
do
        s=$[$s+$i]
done
echo $s

[root@master datas]$ chmod 777 for1.sh 
[root@master datas]$ ./for1.sh 
5050

3.基本语法2

for 变量 in 值1 值2 值3… 
  do 
    程序 
  done

4.案例实操

(1)打印所有输入参数

[root@master datas]$ touch for2.sh
[root@master datas]$ vim for2.sh

#!/bin/bash
#打印数字

for i in $*
    do
      echo "ban zhang love $i "
    done

[root@master datas]$ chmod 777 for2.sh 
[root@master datas]$ bash for2.sh cls xz bd
ban zhang love cls
ban zhang love xz
ban zhang love b

(2)比较$*$@区别

  • (a)$*$@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 $2 …$n的形式输出所有参数。

    [root@master datas]$ touch for.sh
    [root@master datas]$ vim for.sh
    
    #!/bin/bash 
    
    for i in $*
    do
          echo "ban zhang love $i "
    done
    
    for j in $@
    do      
            echo "ban zhang love $j"
    done
    
    [root@master datas]$ bash for.sh cls xz bd
    ban zhang love cls 
    ban zhang love xz 
    ban zhang love bd 
    ban zhang love cls
    ban zhang love xz
    ban zhang love bd
    
  • (b)当它们被双引号“”包含时,“$*”会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输出所有参数;“$@”还是会将各个参数分开,以“$1” “$2”…”$n”的形式输出所有参数。

    [root@master datas]$ vim for.sh
    
    #!/bin/bash 
    
    for i in "$*" 
    #$*中的所有参数看成是一个整体,所以这个for循环只会循环一次 
            do 
                    echo "ban zhang love $i"
            done 
    
    for j in "$@" 
    #$@中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次 
            do 
                    echo "ban zhang love $j" 
    done
    
    [root@master datas]$ chmod 777 for.sh
    [root@master datas]$ bash for.sh cls xz bd
    ban zhang love cls xz bd
    ban zhang love cls
    ban zhang love xz
    ban zhang love bd
    

7.4 while 循环

1.基本语法

while [ 条件判断式 ] 
  do 
    程序
  done

2.案例实操

(1)从1加到100

[root@master datas]$ touch while.sh
[root@master datas]$ vim while.sh

#!/bin/bash
s=0
i=1
while [ $i -le 100 ] #i的值小于100,并不是i小于100,所以用$i
do
        s=$[$s+$i]
        i=$[$i+1]
done

echo $s

[root@master datas]$ chmod 777 while.sh 
[root@master datas]$ ./while.sh 
5050

第8章 read读取控制台输入

1.基本语法

read(选项)(参数)

选项:

  • -p:指定读取值时的提示符;
  • -t:指定读取值时等待的时间(秒)。

参数

  • 变量:指定读取值的变量名

2.案例实操

(1)提示7秒内,读取控制台输入的名称

[root@master datas]$ touch read.sh
[root@master datas]$ vim read.sh

#!/bin/bash

read -t 7 -p "Enter your name in 7 seconds " NAME
echo $NAME

[root@master datas]$ ./read.sh 
Enter your name in 7 seconds xiaoze
xiaoze

第9章 函数

9.1 系统函数

1.basename基本语法(返回文件名)

basename [string / pathname] [suffix]  	

(功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。

选项:suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。

2.案例实操

(1)截取该/home/atguigu/banzhang.txt路径的文件名称

[root@master datas]$ basename /home/atguigu/banzhang.txt 
banzhang.txt
[root@master datas]$ basename /home/atguigu/banzhang.txt .txt
banzhang

3 . dirname基本语法(返回路径)

dirname 文件绝对路径		

(功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))

4.案例实操

(1)获取banzhang.txt文件的路径

[root@master ~]$ dirname /home/atguigu/banzhang.txt 
/home/atguigu

9.2 自定义函数

1.基本语法

[ function ] funname[()]
{
	Action;
	[return int;]
}
funname

2.经验技巧

  • 必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
  • 函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)

3.案例实操

(1)计算两个输入参数的和

[root@master datas]$ touch fun.sh
[root@master datas]$ vim fun.sh

#!/bin/bash
function sum()
{
    s=0
    s=$[ $1 + $2 ]
    echo "$s"
}

read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
sum $n1 $n2;

[root@master datas]$ chmod 777 fun.sh
[root@master datas]$ ./fun.sh 
Please input the number1: 2
Please input the number2: 5
7

第10章 输入/输出重定向

10.1 重定向介绍

大多数 UNIX系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。

重定向命令列表如下

命令说明
command > file将输出重定向到 file
command < file将输入重定向到 file
command >> file将输出以追加的方式重定向到 file
n > file将文件描述符为 n 的文件重定向到 file
n >> file将文件描述符为 n 的文件以追加的方式重定向到 file
n >& m将输出文件 m 和 n 合并
n <& m将输入文件 m 和 n 合并
<< tag将开始标记 tag 和结束标记 tag 之间的内容作为输入

注意:文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)

10.2 输出重定向

重定向一般通过在命令间插入特定的符号来实现。特别的,这些符号的语法如下所示:

command1 > file1

上面这个命令执行command1然后将输出的内容存入file1。

注意:任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用>>操作符。

实例

1)执行下面的 who 命令,它将命令的完整的输出重定向在用户文件中(users):

$ who > users

执行后,并没有在终端输出信息,这是因为输出已被从默认的标准输出设备(终端)重定向到指定的文件。

你可以使用 cat 命令查看文件内容:

$ cat users
_mbsetupuser console  Oct 31 17:35 
tianqixin    console  Oct 31 17:35 
tianqixin    ttys000  Dec  1 11:33 

2)输出重定向会覆盖文件内容,请看下面的例子:

$ echo "你好!!!" > users
$ cat users
你好!!
$

3)如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,例如:

$ echo "你好!!" >> users
$ cat users
你好!!
你好!!
$

10.3 输入重定向

和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:

command1 < file1

这样,本来需要从键盘获取输入的命令会转移到文件读取内容。

注意:输出重定向是大于号(>),输入重定向是小于号(<)。

实例

1)接着以上实例,我们需要统计 users 文件的行数,执行以下命令:

$ wc -l users
       2 users

2)也可以将输入重定向到 users 文件:

$  wc -l < users
       2 

注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。

3)同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。

command1 < infile > outfile

10.4 重定向深入讲解

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

如果希望 stderr 重定向到 file,可以这样写:

$ command 2>file

如果希望 stderr 追加到 file 文件末尾,可以这样写:

$ command 2>>file

2 表示标准错误文件(stderr)。

如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

$ command > file 2>&1

或者

$ command >> file 2>&1

如果希望对 stdin 和 stdout 都重定向,可以这样写:

$ command < file1 >file2

command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。

10.5 Here Document

Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。

它的基本的形式如下:

command << delimiter
    document
delimiter

它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。

注意

  • 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
  • 开始的delimiter前后的空格会被忽略掉。

实例

1)在命令行中通过 wc -l 命令计算 Here Document 的行数:

$ wc -l << EOF
    欢迎
    光临
EOF
2          # 输出结果为 2 行
$

2)我们也可以将 Here Document 用在脚本中,例如:

#!/bin/bash

cat << EOF
欢迎
光临
EOF

执行以上脚本,输出结果:

欢迎
光临

10.6 /dev/null 文件

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

$ command > /dev/null

如果希望屏蔽 stdout 和 stderr,可以这样写:

$ command > /dev/null 2>&1

注意

  • 0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

  • 这里的 2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出。

第11章 Shell工具(重点)

11.1 cut

cut 的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

1.基本用法

cut [选项参数]  filename

说明:默认分隔符是制表符

2.选项参数说明

选项参数功能
-f列号,提取第几列
-d分隔符,按照指定分隔符分割列

3.案例实操

(0)数据准备

[root@master datas]$ touch cut.txt
[root@master datas]$ vim cut.txt
dong shen
guan zhen
wo  wo
lai  lai
le  le

(1)切割 cut.txt 第一列

[root@master datas]$ cut -d " " -f 1 cut.txt 
dong
guan
wo
lai
le

(2)切割 cut.txt 第二、三列

[root@master datas]$ cut -d " " -f 2,3 cut.txt 
shen
zhen
 wo
 lai
 le

(3)在 cut.txt 文件中切割出guan

[root@master datas]$ cat cut.txt | grep "guan" | cut -d " " -f 1
guan

(4)选取系统PATH变量值,第2个“ :”开始后的所有路径:

[root@master datas]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/atguigu/bin

[atguigu@hadoop102 datas]$ echo $PATH | cut -d : -f 3- #3-:表示第三列开始后面的所有
/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/atguigu/bin

(5)切割 ifconfig 后打印的IP地址

[root@master datas]$ ifconfig eth0 | grep "inet addr" | cut -d : -f 2 | cut -d " " -f1
192.168.1.102

11.2 sed

sed是一种编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

1.基本用法

sed [选项参数]  ‘command’  filename

2.选项参数说明

选项参数功能
-e直接在指令列模式上进行sed的动作编辑。

3.命令功能描述

命令功能
a新增,a的后面可以接字串,在下一行出现
d删除
s查找并替换

4.案例实操

(0)数据准备

[root@master datas]$ touch sed.txt
[root@master datas]$ vim sed.txt
dong shen
guan zhen
wo  wo
lai  lai

le  le

(1)将“mei nv”这个单词插入到sed.txt第二行下,打印(原文件并不改变)。

[root@master datas]$ sed '2a mei nv' sed.txt #2a:表示第二行下
dong shen
guan zhen
mei nv
wo  wo
lai  lai

le  le
[root@master datas]$ cat sed.txt 
dong shen
guan zhen
wo  wo
lai  lai

le  le

注意:文件并没有改变

(2)删除sed.txt文件所有包含wo的行

[root@master datas]$ sed '/wo/d' sed.txt
dong shen
guan zhen
lai  lai

le  le

(3)将sed.txt文件中wo替换为ni

[root@master datas]$ sed 's/wo/ni/g' sed.txt #g:表示全局替换
dong shen
guan zhen
ni  ni
lai  lai

le  le

注意:‘g’表示global,全部替换

(4)将sed.txt文件中的第二行删除并将wo替换为ni

[root@master datas]$ sed -e '2d' -e 's/wo/ni/g' sed.txt  
dong shen
ni  ni
lai  lai

le  le

11.3 awk

一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

1.基本用法

awk [选项参数] ‘pattern1{action1}  pattern2{action2}...’ filename

pattern:表示AWK在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令

2.选项参数说明

选项参数功能
-F指定输入文件折分隔符(切割符)
-v赋值一个用户定义变量

3.案例实操
(0)原数据
在这里插入图片描述

(1)搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。正则表达式不会的看第13章!!!

[root@master datas]$ awk -F : '/^root/{print $7}' passwd #/^:表示开头
/bin/bash

(2)搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。

[root@master datas]$ awk -F : '/^root/{print $1","$7}' passwd 
root,/bin/bash

注意:只有匹配了pattern的行才会执行action

(3)只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell在最后一行添加"dahaige,/bin/zuishuai"。

[root@master datas]$ awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END {print "dahaige,/bin/zuishuai"}' passwd #BEGIN:表示开头位置
user, shell
root,/bin/bash
bin,/sbin/nologin
。。。
atguigu,/bin/bash
dahaige,/bin/zuishuai

注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。

(4)将passwd文件中的用户id增加数值1并输出

[root@master datas]$ awk -v i=1 -F : '{print $3+i}' passwd
1
2
3
4

4.awk的内置变量

变量说明
FILENAME文件名
NR已读的记录数(行数)
NF浏览记录的域的个数(切割后,列的个数)

5.案例实操

(1)统计passwd文件名,每行的行号,每行的列数

[root@master datas]$ awk -F : '{print "filename:"  FILENAME ", linenumber:" NR  ",columns:" NF}' passwd 
filename:passwd, linenumber:1,columns:7
filename:passwd, linenumber:2,columns:7
filename:passwd, linenumber:3,columns:7

(2)切割IP

[root@master datas]$ ifconfig eth0 | grep "inet addr" | awk -F : '{print $2}' | awk -F " " '{print $1}' 
192.168.1.102

(3)查询sed.txt中空行所在的行号

[root@master datas]$ awk '/^$/{print NR}' sed.txt #/^$:表示空行
5

11.4 sort

sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。

1.基本语法

sort(选项)(参数) filename
选项说明
-n依照数值的大小排序
-r以相反的顺序来排序
-t设置排序时所用的分隔字符
-k指定需要排序的列

参数:指定待排序的文件列表

2 . 案例实操

(0)数据准备

[root@master datas]$ touch sort.sh
[root@master datas]$ vim sort.sh 
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6

(1)按照“:”分割后的第三列倒序排序。

[root@master datas]$ sort -t : -nrk 3  sort.sh 
bb:40:5.4
bd:20:4.2
cls:10:3.5
xz:50:2.3
ss:30:1.6

第12章 企业真实面试题(重点)

12.1 京东

问题1:使用Linux命令查询file1中空行所在的行号

答案:

[root@master datas]$ awk '/^$/{print NR}' sed.txt 
5

问题2:有文件chengji.txt内容如下:

张三 40
李四 50
王五 60
使用Linux命令计算第二列的和并输出
[atguigu@hadoop102 datas]$ cat chengji.txt | awk -F " " '{sum+=$2} END {print sum}'
150

12.2 搜狐&和讯网

问题1:Shell脚本里如何检查一个文件是否存在?如果不存在该如何处理?

#!/bin/bash

if [ -e file.txt ]; then
   echo "文件存在!"
else
   echo "文件不存在!"
fi

12.3 新浪

问题1:用shell写一个脚本,对文本中无序的一列数字排序,并求和

[root@master ~]$ cat test.txt
9
8
7
6
5
4
3
2
10
1
[root@master ~]$ sort -n test.txt | awk '{a+=$0;print $0} END {print "SUM="a}'
1
2
3
4
5
6
7
8
9
10
SUM=55

12.3 金和网络

问题1:请用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”shen”的文件名称

[root@master datas]$ grep -r "shen" /home | cut -d ":" -f 1
/home/atguigu/datas/sed.txt
/home/atguigu/datas/cut.txt

第13章 正则表达式语法大全

字符说明
\将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,“n"匹配字符"n”。"\n"匹配换行符。序列"\\“匹配”","\(“匹配”("。
^匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与"\n"或"\r"之后的位置匹配。
$匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与"\n"或"\r"之前的位置匹配。
*零次或多次匹配前面的字符或子表达式。例如,zo* 匹配"z"和"zoo"。* 等效于 {0,}。
+一次或多次匹配前面的字符或子表达式。例如,"zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。
?零次或一次匹配前面的字符或子表达式。例如,"do(es)?“匹配"do"或"does"中的"do”。? 等效于 {0,1}。
{n}n 是非负整数。正好匹配 n 次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。
{n,}n 是非负整数。至少匹配 n 次。例如,"o{2,}“不匹配"Bob"中的"o”,而匹配"foooood"中的所有 o。"o{1,}“等效于"o+”。"o{0,}“等效于"o*”。
{n,m}M 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的头三个 o。‘o{0,1}’ 等效于 ‘o?’。注意:您不能将空格插入逗号和数字之间。
?当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?“只匹配单个"o”,而"o+“匹配所有"o”。
.匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。
(pattern)匹配 pattern 并捕获该匹配的子表达式。可以使用 $0…$9 属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"(“或者”)"。
(?:pattern)匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用"or"字符 (|) 组合模式部件的情况很有用。例如,'industr(?:y|ies) 是比 'industry|industries' 更经济的表达式。
(?=pattern)执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,’Windows (?=95|98|NT|2000)’ 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。
(?!pattern)执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,’Windows (?!95|98|NT|2000)’ 匹配"Windows 3.1"中的 “Windows”,但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。
x|y匹配 x 或 y。例如,’z|food’ 匹配"z"或"food"。’(z|f)ood’ 匹配"zood"或"food"。
[xyz]字符集。匹配包含的任一字符。例如,"[abc]“匹配"plain"中的"a”。
[^xyz]反向字符集。匹配未包含的任何字符。例如,"[^abc]“匹配"plain"中"p”,“l”,“i”,“n”。
[a-z]字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母。
[^a-z]反向范围字符。匹配不在指定的范围内的任何字符。例如,"[^a-z]"匹配任何不在"a"到"z"范围内的任何字符。
\b匹配一个字边界,即字与空格间的位置。例如,“er\b"匹配"never"中的"er”,但不匹配"verb"中的"er"。
\B非字边界匹配。“er\B"匹配"verb"中的"er”,但不匹配"never"中的"er"。
\cx匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回车符。x 的值必须在 A-Z 或 a-z 之间。如果不是这样,则假定 c 就是"c"字符本身。
\d数字字符匹配。等效于 [0-9]。
\D非数字字符匹配。等效于 [^0-9]。
\f换页符匹配。等效于 \x0c 和 \cL。
第1章 BashShell命令 6 1.1 Shell提示符 6 1.2 文件与目录Shell命令 7 1.2.1 更改目录命令(cd) 7 1.2.2 列表命令(ls) 7 1.2.3 操作文件命令 10 1.2.4 目录处理命令 14 1.2.5 查看文件内容命令 15 1.3 监控程序 20 1.3.1 进程查看 20 1.3.2 实时进程监控 22 1.3.3 停止进程 24 1.4 监控磁盘空间 25 1.4.1 挂载介质 25 1.4.2 使用df命令 26 1.4.3使用du命令 27 1.5 操作数据文件 28 1.5.1 数据排序(sort) 28 1.5.2 搜索数据 (grep) 30 1.5.3 压缩数据 30 1.5.4 归档数据(tar) 33 1.6 使用Linux环境变量 34 1.6.1 设置环境变量 34 1.6.2 默认的shell环境变量与path变量的设置 37 1.7 Linux文件权限 40 1.7.1 Linux安全性 40 1.7.2 使用Linux用户组 46 1.7.3 解码文件权限 47 1.7.4 修改安全设置 49 1.8 vim编辑器 52 第2章 基本脚本编译 54 2.1 创建脚本与使用变量 54 2.1.1 创建脚本 54 2.1.2 使用变量 55 2.2 重定向输入输出与数学计算 57 2.2.1 输出重定向 57 2.2.2 输入重定向 58 2.2.3 管道 58 2.2.4 数学计算 58 2.3 退出脚本 60 第3章 结构化命令 61 3.1 if语句 61 3.1.1 if-then语句 61 3.1.2 if-then-else语句 61 3.1.3 嵌套if语句 62 3.2 if条件语句 63 3.2.1 数值比较 63 3.2.2字符串比较 64 3.2.3 文件比较 65 3.2.4 复合条件检查 65 3.3 if-then的高级特征与case命令 66 3.3.1 使用双圆括号 66 3.3.2 使用双方括号 67 3.3.3 case命令 67 3.4 for命令 67 3.4.1 读取列表 68 3.4.2 读取变量与读取命令 69 3.4.3 改变字段分隔符与使用通配符读取目录 69 3.4.5 C式的for命令 70 3.5 while、until命令 71 3.5.1 使用多条测试命令 71 3.5.2 until命令与循环嵌套 72 3.6 文件数据的循环与控制循环 73 3.6.1 文件数据的循环 73 3.6.2 break命令 73 3.6.3 continue命令 75 第4章 处理用户输入与显示数据 76 4.1 命令行参数与特殊的参数变量 76 4.1.1 读取参数 76 4.1.2 读取程序名称 77 4.1.3 测试参数 77 4.1.4 参数计数 77 4.1.5 获取所有数据 78 4.2 移位与选项 79 4.2.1 移位 79 4.2.2 找出选项 79 4.2.3 使用getopt命令 81 4.2.4 更高级的getopts命令 83 4.2.4 标准化选项 84 4.3 获取用户输入 84 4.3.1 基本读取 84 4.3.2 计时 85 4.3.3 默读与文件读取 85 4.4 显示数据 86 4.4.1 标准文件描述符 86 4.4.2 重定向错误 87 4.4.3 临时重定向 88 4.4.4永久重定向 88 4.4.5 在脚本中重定向输入 89 4.5 创建自己的重定向 90 4.5.1 创建输出文件描述符 90 4.5.2 重定向文件描述符 90 4.5.3 创建输入文件描述符 91 4.5.4 创建读取/写入文件描述符 91 4.5.5 关闭文件描述符 92 4.5.6列出开发文件描述符 92 4.5.7禁止命令输出 94 4.6 使用临时文件 94 4.6.1 创建本地临时文件 94 4.6.2 在/temp中创建临时文件 95 4.6.3 创建临时目录 96 4.6.4 记录消息 96 第5章 脚本控制 97 5.1 处理信号 97 5.1.1 Linux信号回顾 97 5.1.2 生成信号 97 5.1.3捕获信号 99 5.1.4捕获脚本退出 99 5.1.4移除捕获 100 5.2 以后台模式运行脚本 100 5.3 作业控制 102 5.3.1查看作业 102 5.3.2重新启动停止的作业 103 5.4 nice与renice命令 104 5.4.1 nice命令 104 5.4.2 renice命令 104 5.5 定时运行脚本 105 5.5.1使用at命令调度作业 105 5.5.2使用batch命令调 107 5.5.3 调用定期脚本 107 5.6 从头开始 109 5.6.1在启动时启动脚本 109 5.6.2随新shell一起启动 109 第6章 创建函数 110 6.1 基本脚本函数 110 6.1.1 创建函数 110 6.1.2 使用函数 110 6.2 返回值 111 6.2.1 默认退出状态 111 6.2.2 使用return命令 111 6.2.3 使用函数输出 112 6.3 在函数中使用变量 112 6.3.1 向函数传递参数 112 6.3.2 在函数中处理变量 113 6.4 数组变量与函数 114 6.4.1 向函数传递数组 114 6.4.2从函数返回数组 115 6.5 函数递归与创建库 116 6.5.1函数递归 116 6.5.2 创建库 116 6.6 在命令行中使用函数 117 6.6.1在命令行创建函数 117 6.6.2在.bashrc文件中定义函数 117 6.7 select命令使用 119 第7章 sed、gawk介绍与正则表达式 120 7.1 sed编辑器 120 7.1.1 在命令行中定义编辑器命令 120 7.1.2 在命令行中使用多个编辑器命令 121 7.1.3 从文件读取编辑器命令 121 7.2 gawk程序 122 7.2.1 gawk命令格式 122 7.2.2 自命令行读取程序脚本 122 7.2.3 使用数据字段变量 123 7.2.4 在程序脚本中使用多个命令 124 7.2.5从文件读取程序 124 7.2.6 在处理数据之前运行脚本 125 7.2.7 在处理数据之后运行脚本 125 7.3 sed编辑器基础知识 126 7.3.1 更多替换选项 126 7.3.2 使用地址 127 7.3.3 删除行 128 7.3.4 插入和附加文本 129
评论 53
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

袁袁袁袁满

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

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

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

打赏作者

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

抵扣说明:

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

余额充值