shell快速入门

Shell入门

学习shell脚本的时候,整理了一下知识点,适合新手入门。

Shell概述

shell是一个命令行解释器,它能接受应用程序或者用户命令,然后调用系统内核;同时还是一个编程语言。

Linux提供的Shell解析器有:

[hadoop@hdp01 ~]$ cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh

bash和sh的关系:

[hadoop@hdp01 bin]$ ll | grep bash
-rwxr-xr-x. 1 root root 941720 Jul 24  2015 bash
lrwxrwxrwx. 1 root root      4 Aug  5  2019 sh -> bash
# 链接关系

Centos默认的解析器是bash

Shell入门

创建一个Shell脚本,输出helloworld(helloworld.sh)

# 指定解析器
#!/bin/bash
echo "helloworld"

脚本的常用执行方式:

  1. 采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)

    [hadoop@hdp01 ~]$ bash helloworld.sh
    [hadoop@hdp01 ~]$ bash /home/hadoop/helloworld.sh
    
  2. 采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)

    [hadoop@hdp01 ~]$ chmod +x helloworld.sh
    [hadoop@hdp01 ~]$ ./helloworld.sh
    [hadoop@hdp01 ~]$ /home/hadoop/helloworld.sh
    

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

变量

系统预定义变量

常用系统变量

$HOME、$PWD、$USER、$SHELL

案例实操
  1. 查看系统变量的值

    [hadoop@hdp01 ~]$ echo $HOME
    /home/hadoop
    
    
  2. 显示当前Shell中所有的变量

    [hadoop@hdp01 ~]$ set
    BASH=/bin/bash
    ......
    

自定义变量

1)基本语法

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

(2)撤销变量:unset 变量

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

2)变量定义规则

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

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

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

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

注意:1. 声明静态的变量B=2,不能重新赋值;2. 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算;3. 变量的值如果有空格,需要使用双引号或单引号括起来;4. 可把变量提升为全局环境变量,可供其他Shell程序使用(代码如下)。

helloworld.sh

#!/bin/bash

echo "helloworld"
echo $B
[hadoop@hdp01 ~]$ B=2
[hadoop@hdp01 ~]$ export B
[hadoop@hdp01 ~]$ bash helloworld.sh 
hello world
2

特殊变量

$n

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

[hadoop@hdp01 ~]$ touch parameter.sh 
[hadoop@hdp01 ~]$ vim parameter.sh

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

[hadoop@hdp01 ~]$ chmod 777 parameter.sh

[hadoop@hdp01 ~]$ ./parameter.sh cls  xz
./parameter.sh  cls   xz
$#

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

[hadoop@hdp01 ~]$ vim parameter.sh

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

[hadoop@hdp01 ~]$chmod 777 parameter.sh

[hadoop@hdp01 ~]$ ./parameter.sh cls  xz
parameter.sh cls xz 
2
$@、$*

$ * 功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体

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

[hadoop@hdp01 ~]$ vim parameter.sh

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

[hadoop@hdp01 ~]$ bash parameter.sh 1 2 3
parameter.sh  1   2
3
1 2 3
1 2 3
$?

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

[hadoop@hdp01 ~]$ ./helloworld.sh 
hello world
[hadoop@hdp01 ~]$ echo $?
0

运算符

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

计算(2+3)*4的值

[hadoop@hdp01 ~]$ c=$[(2+3)*4]
[hadoop@hdp01 ~]$ echo $c
20

条件判断

基本语法

(1)test condition

(2)[ condition ](注意condition前后要有空格)

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

常用判断条件

(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)

23是否大于等于22
[hadoop@hdp01 ~]$ [ 23 -ge 22 ]
[hadoop@hdp01 ~]$ echo $?
0
helloworld.sh是否具有写权限
[hadoop@hdp01 ~]$ [ -w helloworld.sh ]
[hadoop@hdp01 ~]$ echo $?
0
/home/hadoop/cls.txt目录中的文件是否存在
[hadoop@hdp01 ~]$ [ -e /home/hadoop/cls.txt ]
[hadoop@hdp01 ~]$ echo $?
1

##流程控制(重点)

if 判断

if [ 条件判断式 ]

then

程序

fi

或者

if [ 条件判断式 ]

then

程序

elif [ 条件判断式 ]

​ then

​ 程序

else

​ 程序

fi

​ 注意事项:

(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格

(2)if后要有空格

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

[hadoop@hdp01 ~]$ touch if.sh
[hadoop@hdp01 ~]$ vim if.sh

#!/bin/bash

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

[hadoop@hdp01 ~]$ chmod 777 if.sh 
[hadoop@hdp01 ~]$ ./if.sh 1
banzhang zhen shuai

case 语句

case $变量名 in

“值1”)

如果变量的值等于值1,则执行程序1

;;

“值2”)

如果变量的值等于值2,则执行程序2

;;

…省略其他分支…

*)

如果变量的值都不是以上的值,则执行此程序

;;

esac

注意事项:

(1)case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。

(2)双分号“****;;****”表示命令序列结束,相当于java中的break。

(3)最后的“*)”表示默认模式,相当于java中的default。

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

[hadoop@hdp01 ~]$ touch case.sh
[hadoop@hdp01 ~]$ vim case.sh

!/bin/bash

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

"2")
        echo "cls"
;;
*)
        echo "renyao"
;;
esac

[hadoop@hdp01 ~]$ chmod 777 case.sh
[hadoop@hdp01 ~]$ ./case.sh 1
1

for 循环

基础语法一

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

do

程序

done

从1加到100

#!/bin/bash
for((i=0;i<=100;i++))
do 
  s=$[$s+$i]
done
echo $s

语法基础二

for 变量 in 值1 值2 值3…

do

​ 程序

done

  1. 打印所有输入参数
#!/bin/bash
for i in $*
do 
   echo "ban zhang love $i "
done
for i in $@
do 
    echo "ban zhang love $i "
done 
  
[hadoop@hdp01 ~]$ bash helloworld.sh ls zs ww
ban zhang love ls 
ban zhang love zs 
ban zhang love ww 
ban zhang love ls 
ban zhang love zs 
ban zhang love ww 
  1. 比较$*和$@的区别

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

当它们被双引号“”包含时,“$*”会将所有的参数作为一个整体,以“$1 ​$2 …​$n”的形式输出所有参数;“​$@”会将各个参数分开,以“​$1” “​$2”…”$n”的形式输出所有参数。

#!/bin/bash
for i in "$*"
do 
   echo "ban zhang love $i "
done
for i in "$@"
do 
  echo "ban zhang love $i "
done 
  
[hadoop@hdp01 ~]$ bash helloworld.sh ls zs ww
ban zhang love ls zs ww 
ban zhang love ls 
ban zhang love zs 
ban zhang love ww 

while 循环

while [ 条件判断式 ]

​ do

​ 程序

​ done

注意 while 和 [ ] 之间要有空格

从1加到100

#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do 
  s=$[$s+$i]
  i=$[$i+1]
done
echo $s

read 读取控制台输入

read(选项)(参数)

选项:

-p:指定读取值时的提示符;

-t:指定读取值时等待的时间(秒)。

参数

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

#!/bin/bash
read -t 10 -p "Enter your name:" NAME
echo $NAME

[hadoop@hdp01 ~]$ bash helloworld.sh 
Enter your name:lisi
[hadoop@hdp01 ~]$ lisi

函数

系统函数

basename

basename [string / pathname] [suffix]

功能描述:

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

​ 选项:

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

[hadoop@hdp01 ~]$ basename /home/hadoop/helloworld.sh 
helloworld.sh
[hadoop@hdp01 ~]$ basename /home/hadoop/helloworld.sh sh
helloworld.
dirname

dirname 文件绝对路径

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

[hadoop@hdp01 ~]$ dirname /home/hadoop/helloworld.sh 
/home/hadoop

自定义函数

[ function ] funname[()]

{

​ Action;

​ [return int;]

}

funname

经验技巧

(1)必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。

(2)函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)

计算两个输入参数的和

#!/bin/bash
function sum()
{
  s=$(($1+$2))
  echo $s
}
echo "Enter Fisrt Number:"
read a
echo "Enter Second Number:"
read b
sum $a $b

[hadoop@hdp01 ~]$ bash helloworld.sh 
Enter Fisrt Number:
1
Enter Second Number:
2
3

Shell工具(重点)

cut

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

cut [选项参数] filename

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

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

(1)数据准备

[hadoop@hdp01 ~]$ touch cut.txt
[hadoop@hdp01 ~]$ vim cut.txt
[hadoop@hdp01 ~]$ cat cut.txt 
dong shen
guan zhen
wo  wo
lai  lai
le  le

(2)切割cut.txt第一列

[hadoop@hdp01 ~]$ cut -d " " -f 1 cut.txt 
dong
guan
wo
lai
le

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

[hadoop@hdp01 ~]$ cut -d " " -f 2,3  cut.txt 
shen
zhen
 wo
 lai
 le

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

[hadoop@hdp01 ~]$ cat cut.txt | grep "guan" | cut -d " " -f 1
guan

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

[hadoop@hdp01 ~]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/opt/jdk1.8.0_73/bin:/home/hadoop/app/hadoop-2.7.7/bin:/home/hadoop/app/hadoop-2.7.7/sbin:/home/hadoop/hbase-1.2.6/bin:/home/hadoop/scala-2.11.8/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hadoop/zookeeper-3.4.13/sbin:/home/hadoop/bin:/home/hadoop/hadoop-2.7.7/bin:/home/hadoop/hadoop-2.7.7/sbin:/home/hadoop/zookeeper-3.4.13/bin:/home/hadoop/redis/bin:/home/hadoop/spark/bin:/home/hadoop/spark/sbin:/home/hadoop/kafka/bin
[hadoop@hdp01 ~]$ echo $PATH | cut -d ":" -f 3-
/bin:/usr/bin:/opt/jdk1.8.0_73/bin:/home/hadoop/app/hadoop-2.7.7/bin:/home/hadoop/app/hadoop-2.7.7/sbin:/home/hadoop/hbase-1.2.6/bin:/home/hadoop/scala-2.11.8/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hadoop/zookeeper-3.4.13/sbin:/home/hadoop/bin:/home/hadoop/hadoop-2.7.7/bin:/home/hadoop/hadoop-2.7.7/sbin:/home/hadoop/zookeeper-3.4.13/bin:/home/hadoop/redis/bin:/home/hadoop/spark/bin:/home/hadoop/spark/sbin:/home/hadoop/kafka/bin

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

[hadoop@hdp01 ~]$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:A2:65:A5  
          inet addr:192.168.4.101  Bcast:192.168.4.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fea2:65a5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7298 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4927 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:700185 (683.7 KiB)  TX bytes:655451 (640.0 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:576 (576.0 b)  TX bytes:576 (576.0 b)
[hadoop@hdp01 ~]$ ifconfig eth0 | grep "inet addr" | cut -d ":" -f 2 | cut -d " " -f 1
192.168.4.101

sed

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

sed [选项参数] ‘command’ filename

选项参数命令功能
-e直接在指令列模式上进行sed的动作编辑。
-i直接编辑文件
命令功能描述
a新增,a的后面可以接字串,在下一行出现
d删除
e查找并替换

(1)数据准备

[hadoop@hdp01 ~]$ touch sed.txt
[hadoop@hdp01 ~]$ vim sed.txt
[hadoop@hdp01 ~]$ cat sed.txt 
dong shen
guan zhen
wo  wo
lai  lai

le  le

(2)将“mei nv”这个单词插入到sed.txt第二行下,打印。

[hadoop@hdp01 ~]$ sed '2a meinv' sed.txt 
dong shen
guan zhen
meinv
wo  wo
lai  lai

le  le
[hadoop@hdp01 ~]$ cat sed.txt 
dong shen
guan zhen
wo  wo
lai  lai

le  le

**注意:**文件并没有改变

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

[hadoop@hdp01 ~]$ sed '/wo/d' sed.txt
dong shen
guan zhen
lai  lai

le  le
[hadoop@hdp01 ~]$ cat sed.txt 
dong shen
guan zhen
wo  wo
lai  lai

le  le

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

[hadoop@hdp01 ~]$ sed 's/wo/ni/g' sed.txt
dong shen
guan zhen
ni  ni
lai  lai

le  le

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

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

[hadoop@hdp01 ~]$ sed -e '2d' -e 's/wo/ni/g' sed.txt
dong shen
ni  ni
lai  lai

le  le

awk

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

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

pattern:表示AWK在数据中查找的内容,就是匹配模式

action:在找到匹配内容时所执行的一系列命令

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

(1)数据准备

[hadoop@hdp01 ~]$ cp /etc/passwd ./

(2)搜索passwd文件以root关键字开头的所有行,并输出该行的第7列

[hadoop@hdp01 ~]$ awk -F : '/^root/{print $7}' passwd 
/bin/bash

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

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

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

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

[hadoop@hdp01 ~]$ awk -F : 'BEGIN{print "user,shell"} {print $1","$7} END{print "dahage,/bin/zuishuai"}' passwd
user,shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
halt,/sbin/halt
mail,/sbin/nologin
uucp,/sbin/nologin
operator,/sbin/nologin
games,/sbin/nologin
gopher,/sbin/nologin
ftp,/sbin/nologin
nobody,/sbin/nologin
dbus,/sbin/nologin
usbmuxd,/sbin/nologin
vcsa,/sbin/nologin
rpc,/sbin/nologin
rtkit,/sbin/nologin
avahi-autoipd,/sbin/nologin
abrt,/sbin/nologin
rpcuser,/sbin/nologin
nfsnobody,/sbin/nologin
haldaemon,/sbin/nologin
gdm,/sbin/nologin
ntp,/sbin/nologin
apache,/sbin/nologin
saslauth,/sbin/nologin
postfix,/sbin/nologin
pulse,/sbin/nologin
sshd,/sbin/nologin
tcpdump,/sbin/nologin
hadoop,/bin/bash
mysql,/bin/bash
nginx,/sbin/nologin
dahage,/bin/zuishuai

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

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

[hadoop@hdp01 ~]$ awk -v i=1 -F : '{print $3+i}' passwd 
1
2
3
4
5
6
7
8
9
11
12
13
14
15
100
82
114
70
33
500
171
174
30
65535
69
43
39
49
499
90
498
75
73
501
497
496
awk内置变量
命令功能描述
FILENAME文件名
NR已读的记录数
NF浏览记录的域的个数(切割后,列的个数)

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

[hadoop@hdp01 ~]$ awk -F: '{print "filename:" FILENAME,"rownumber:" NR,"columns:" NF}' passwd 
filename:passwd rownumber:1 columns:7
filename:passwd rownumber:2 columns:7
filename:passwd rownumber:3 columns:7
filename:passwd rownumber:4 columns:7
filename:passwd rownumber:5 columns:7
filename:passwd rownumber:6 columns:7
filename:passwd rownumber:7 columns:7
filename:passwd rownumber:8 columns:7
filename:passwd rownumber:9 columns:7
filename:passwd rownumber:10 columns:7
filename:passwd rownumber:11 columns:7
filename:passwd rownumber:12 columns:7
filename:passwd rownumber:13 columns:7
filename:passwd rownumber:14 columns:7
filename:passwd rownumber:15 columns:7
filename:passwd rownumber:16 columns:7
filename:passwd rownumber:17 columns:7
filename:passwd rownumber:18 columns:7
filename:passwd rownumber:19 columns:7
filename:passwd rownumber:20 columns:7
filename:passwd rownumber:21 columns:7
filename:passwd rownumber:22 columns:7
filename:passwd rownumber:23 columns:7
filename:passwd rownumber:24 columns:7
filename:passwd rownumber:25 columns:7
filename:passwd rownumber:26 columns:7
filename:passwd rownumber:27 columns:7
filename:passwd rownumber:28 columns:7
filename:passwd rownumber:29 columns:7
filename:passwd rownumber:30 columns:7
filename:passwd rownumber:31 columns:7
filename:passwd rownumber:32 columns:7
filename:passwd rownumber:33 columns:7
filename:passwd rownumber:34 columns:7
filename:passwd rownumber:35 columns:7
filename:passwd rownumber:36 columns:7

(2)切割IP

[hadoop@hdp01 ~]$ ifconfig eth0 | grep "inet addr" | awk -F : '{print $2}' | awk -F"  " '{print $1}'
192.168.4.101

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

[hadoop@hdp01 ~]$ awk '/^$/{print NR}' sed.txt
5

sort

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

sort(选项)(参数)

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

(1)数据准备

[hadoop@hdp01 ~]$ touch sort.sh
[hadoop@hdp01 ~]$ vim sort.sh 
[hadoop@hdp01 ~]$ cat sort.sh 
bb:40:5.4
bd:20:4.2
xz:50:2.3
cls:10:3.5
ss:30:1.6

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

[hadoop@hdp01 ~]$ 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

正则表达式入门

正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在Linux中,grep,sed,awk等命令都支持通过正则表达式进行模式匹配。

常规匹配

一串不包含特殊字符的正则表达式匹配它自己,例如:

cat /etc/passwd | grep hadoop

就会匹配所有包含hadoop的行

常用特殊字符

####^

^ 匹配一行的开头,例如:

cat /etc/passwd | grep ^a

会匹配出所有以a开头的行

$

$ 匹配一行的结束,例如

cat /etc/passwd | grep t$

会匹配出所有以t结尾的行

注意:^$匹配什么行? 空行

.

匹配一个任意的字符,例如

cat /etc/passwd | grep r..t

会匹配包含rabt,rbbt,rxdt,root等的所有行

*

* 不单独使用,他和上一个字符连用,表示匹配上一个字符0次或多次,例如

cat /etc/passwd | grep ro*t

会匹配rt, rot, root, rooot, roooot等所有行

[]

[ ] 表示匹配某个范围内的一个字符,例如

[6,8]------匹配6或者8

[a-z]------匹配一个a-z之间的字符

[a-z]*-----匹配任意字母字符串

[a-c, e-f]-匹配a-c或者e-f之间的任意字符

cat /etc/passwd | grep r[a,b,c]*t

会匹配rat, rbt, rabt, rbact等等所有行

\

\ 表示转义,并不会单独使用。由于所有特殊字符都有其特定匹配模式,当我们想匹配某一特殊字符本身时(例如,我想找出所有包含 ‘$’ 的行),就会碰到困难。此时我们就要将转义字符和特殊字符连用,来表示特殊字符本身,例如

cat /etc/passwd | grep a\$b

企业真实面试题

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

张三 40

李四 50

王五 60

使用Linux命令计算第二列的和并输出

[hadoop@hdp01 ~]$ touch chengji.txt
[hadoop@hdp01 ~]$ vim chengji.txt 
[hadoop@hdp01 ~]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'
150

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

#!/bin/bash

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

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

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

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

[hadoop@hdp01 ~]$ grep -r shen /home/hadoop/test | cut -d : -f 1
/home/hadoop/test/sed.txt
/home/hadoop/test/cut.txt
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值