Shell学习笔记

244 阅读5分钟

Shell学习笔记

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

参考别人的shell指令,手打一遍熟悉一下shell指令

常用指令

linux查看cpu个数/核心数

查看物理CPU个数

grep 'physical id' /proc/cpuinfo

查看核心数量

grep 'core id' /proc/cpuinfo

一些情况下,指令我想一次输入去执行,而不是分次,需要用到&& 和 ||了

cmd1 && cmd2

  • 若cmd1执行完毕后且正确($?=0) ,则开始执行cmd2
  • 若cmd1执行完毕后错误($? not equal 0),则cmd2不执行

cmd1 || cmd2

  • 若cmd1执行完毕后且正确($?=0) ,则cmd2不执行
  • 若cmd1执行完毕后错误($? not equal 0),则开始执行cmd2

创建变量

a=1		  # 注意等号两边不要加空格
a=hello	  
a="hello world"		#字符串中间有空格时,需要用双引号或单引号引用内容
a='hello world'		
b='zhangsan'
a="hello ${b}"		#双引号支持转义,${b}会被当做变量,而不是字符串

shell中未引用定义的变量不会报错,但什么也不会发生

做变量和字符串拼接时,需要使用${a}包含变量

a=1111
echo ${a}_bbbb	#输出   1111_bbbb

预定义变量

$PWD
$USER
$HOME
$PATH

数组变量

arr=(1 2 3 4)	#数组变量用()包含,中间用空格分开
arr=('aa' 'bb' 'cc')

echo $arr	#获取数组的第一个元素
echo ${arr[@]}	#获取数组所有的元素
echo ${arr[*]}	#获取数组所有的元素
echo ${#arr[@]}	#获取数组的长度
echo ${#arr[*]}	#获取数组的长度
echo ${arr[0]}	#获取数组下标为0的元素,shell数组下标从0开始

定义一个linux命令的变量,需要用反引号 ``引用

a=`pwd`
echo $a	#打印当前所在的路径

arr=(`ls`)		#相当于把ls命令执行后的内容放到数组内
echo ${arr[@]}	#打印当前路径下的所有文件

shell中对变量进行算数操作

a=5;b=4
echo $((a+b))	#输出9
echo $((a+1))	#输出6
((a=a+5))		#将a+5的值赋给a
echo $a			#输出10
((a++))
echo $a			#输出6

shell中数据比较使用

a=5
b=6
((a<b))
echo $? 	#?用于判断上一条语句的判断结果,为true返回0,否则返回非0

数据类型

a='aaa'
b=123
c=true
d=false

整数和浮点数

echo $((2/3))	#输出0
awk 'BEGIN{print 2/3}'	#输出0.66667 返回浮点数

字符串操作

a="hello from testerhome"
echo ${a:6} #from testerhome;字符串的截取,从第6位开始截取
echo ${a:6:4} #从第6位开始截取,截取4位
echo ${#a} #打印字符串的长度
echo ${a#hello} #对字符串从头开始掐,掐掉hello
echo ${a#*o} #从字符串头开始掐,找到第一个o之前的字符全部掐掉,包括字符o
echo ${a##*o} #贪婪匹配,匹配到最后一个o之前的字符全部掐掉,包括字符o
echo ${a%home} #去尾
echo ${a%h*} #去尾第一个匹配到的字符h,字符h之后的全部去掉,包括h
echo ${a%%h*} #去尾的贪婪匹配
echo ${a/hello/xxx} #将字符穿中hello替换成xxx

输出结果

image-20210520102902709

判断运算

算数判断

[ 2 -eq 2];	#判断2是否等于2(需要注意中括号和数字还有操作符之间都要有空格)
[ 2 -ne 2 ] #不等于判断
[ 2 -gt 2 ] #大于判断
[ 2 -ge 2 ] #大于等于判断
[ 2 -lt 2 ] #小于判断
[ 2 -le 2 ] #小于等于判断	也可以用算术比较((10>=8))
[ 2 -eq 2 -a 3 -ne 4] #判断2等于2并且3不等于4的表达式结果
[ 2 -eq 2 -o 3 -ne 4] #判断2等于2或3不等于4的表达式结果
[ ! 2 -ge 1] #判断2等于1取反后的表达式结果

逻辑与和逻辑或都有短路情况

用于检测Unix文件的各种属性

操作符说明举例
-b file 检测文件是否是块设备文件,如果是,则返回 true[ -b $file ] 返回 false
-c file检测文件是否是字符设备文件,如果是,则返回 true[ -b $file ] 返回 false
-d file检测文件是否是目录,如果是,则返回 true[ -d $file ] 返回 false
-f file检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true[ -f $file ] 返回 true
-g file检测文件是否设置了 SGID 位,如果是,则返回 true[ -g $file ] 返回 false
-k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true[ -k $file ] 返回 false
-p file检测文件是否是具名管道,如果是,则返回 true[ -p $file ] 返回 false
-u file检测文件是否设置了 SUID 位,如果是,则返回 true[ -u $file ] 返回 false
-r file检测文件是否可读,如果是,则返回 true[ -r $file ] 返回 true
-w file检测文件是否可写,如果是,则返回 true[ -w $file ] 返回 true
-x file检测文件是否可执行,如果是,则返回 true[ -x $file ] 返回 true
-s file检测文件是否为空(文件大小是否大于0),不为空返回 true[ -s $file ] 返回 true
-e file检测文件(包括目录)是否存在,如果是,则返回 true[ -e $file ] 返回 true

if结构

if [condition]
then
	...
fi


if [condition]
then
	...
else
	...
fi


if [condition]
then
	...
elif condition2 
then
	...
else commandN
fi

for循环

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

while语句

while condition
do
    command
done

until循环

until condition
do
    command
done

case ... esac

case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

awk命令

语法

awk [选项参数] 'script' var=value file(s)
或者
awk [选项参数] -f scriptfile var=value file(s)

选项参数说明:

  • -F fs or --field-separator fs 指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
  • -v var=value or --asign var=value 赋值一个用户定义变量。
  • -f scripfile or --file scriptfile 从脚本文件中读取awk命令。
  • -mf nnn and -mr nnn 对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
  • -W compact or --compat, -W traditional or --traditional 在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
  • -W copyleft or --copyleft, -W copyright or --copyright 打印简短的版权信息。
  • -W help or --help, -W usage or --usage 打印全部awk选项和每个选项的简短说明。
  • -W lint or --lint 打印不能向传统unix平台移植的结构的警告。
  • -W lint-old or --lint-old 打印关于不能向传统unix平台移植的结构的警告。
  • -W posix 打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符=不能代替^和^=;fflush无效。
  • -W re-interval or --re-inerval 允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
  • -W source program-text or --source program-text 使用program-text作为源代码,可与-f命令混用。
  • -W version or --version 打印bug报告信息的版本。

测试

创建log.txt文件

2 this is a test
3 Are you like awk
This's a test
10 There are orange,apple,mongo

命令

awk '{[pattern] action}' {filenames}   # 行匹配语句 awk '' 只能用单引号

#每行按照空格或TAB分割,输出文本1、4项
[root@feng1 shell]# awk '{print $1,$4}' log.txt
2 a
3 like
This's 
10 orange,apple,mongo

 # 格式化输出
[root@feng1 shell]# awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
2        a         
3        like      
This's             
10       orange,apple,mongo


awk -F  #-F相当于内置变量FS, 指定分割字符

# 使用","分割
[root@feng1 shell]# awk -F, '{print $1,$2}'   log.txt
  this is a test
  Are you like awk
 his's a test
10 There are orange apple

 # 或者使用内建变量
[root@feng1 shell]# awk 'BEGIN{FS=","} {print $1,$2}'     log.txt
  this is a test
  Are you like awk
 his's a test
10 There are orange apple

# 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割
[root@feng1 shell]# awk -F '[ ,]'  '{print $1,$2,$5}'   log.txt
2 this test
3 Are awk
This's a 
10 There apple


awk -v  # 设置变量
[root@feng1 shell]# awk -va=1 '{print $1,$1+a}' log.txt
2 3
3 4
This's 1
10 11
[root@feng1 shell]# awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
2 3 2s
3 4 3s
This's 1 This'ss
10 11 10s
[root@feng1 shell]# 
#过滤第一列大于2的行
[root@feng1 shell]# awk '$1>2' log.txt    #命令
3 Are you like awk
This's a test
10 There are orange,apple,mongo


#过滤第一列等于2的行
[root@feng1 shell]# awk '$1==2 {print $1,$3}' log.txt    #命令
2 is

#过滤第一列大于2并且第二列等于'Are'的行
[root@feng1 shell]# awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt    #命令
3 Are you

# 输出第二列包含 "th",并打印第二列与第四列
[root@feng1 shell]# awk '$2 ~ /th/ {print $2,$4}' log.txt
this a

# 输出包含 "re" 的行
[root@feng1 shell]# awk '/re/ ' log.txt
3 Are you like awk
10 There are orange,apple,mongo

#忽略大小写
[root@feng1 shell]# awk 'BEGIN{IGNORECASE=1} /this/' log.txt
2 this is a test
This's a test

#模式取反
[root@feng1 shell]# awk '$2 !~ /th/ {print $2,$4}' log.txt
Are like
a 
There orange,apple,mongo
[root@feng1 shell]# awk '!/th/ {print $2,$4}' log.txt
Are like
a 
There orange,apple,mongo

脚本测试

在创建一个score.txt和cal.awk脚本

Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

cal.awk

#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

运行

[root@feng1 shell]# awk -f cal.awk score.txt 
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350 
AVERAGE:     63.80    78.60    70.00

sed命令

Linux sed 命令是利用脚本来处理文本文件。

sed 可依照脚本的指令来处理、编辑文本文件。

Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

语法

sed [-hnV][-e<script>][-f<script文件>][文本文件]

参数说明

  • -e
  • -f<script文件>或--file=<script文件> 以选项中指定的script文件来处理输入的文本文件。
  • -h或--help 显示帮助。
  • -n或--quiet或--silent 仅显示script处理后的结果。
  • -V或--version 显示版本信息。

动作说明

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

测试

新建一个testfile.txt文件

HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 

在testfile文件的第四行后添加一行,并将结果输出到标准输出,在命令行提示符下输入如下命令:

[root@feng1 shell]# sed -e 4a\newLine testfile.txt 
HELLO LINUX!  
Linux is a free unix-type opterating system.  
This is a linux testfile!  
Linux test 
newLine
[root@feng1 shell]#