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
输出结果
判断运算
算数判断
[ 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]#