shell 命令专栏总结
一、菜鸟教程
1、只读变量 readonly
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
#!/bin/bash
myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com"
/bin/sh: NAME: This variable is read only.
2、单引号与双引号的区别
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;但双引号中可以有变量
3、字符串应用
3.1 获取字符串长度
使用 ${#string}或者 ${#string[0]} 获取字符串长度;
3.2 截取子字符串
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
4、Shell 数组
4.1 数组定义、取值
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。用括号表示数组,用空格分隔元素,形式如下:
array_name=(value0 value1 value2 value3)
# 或者
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
取值
valuen=${array_name[n]}
4.2 数组的 '@' 位存储所有元素
- 取数组长度,即取 ‘@‘ 位的长度
echo ${#array_name[@]}
5、多行注释
使用 Here 文档进行多行注释,句型可以为
:<<EOF
content
EOF
# 或者 : + 空格 + 单引号
: '
content
'
6、Shell 传递参数
- 具体传递参数:
$n脚本内获取参数的格式为 $n,n 代表一个数字,0为执行语句,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数。
- 传递到脚本的参数个数:
$# - 脚本运行的当前进程ID号:
$$ - 以一个单字符串显示所有向脚本传递的参数:
$*假设在脚本运行时写了三个参数 1、2、3,则 " * " 等价于 "1 2 3"(传递了一个参数)
- 以字符串数组显示所有向脚本传递的参数:
$@假设在脚本运行时写了三个参数 1、2、3,则"@" 等价于 "1" "2" "3"(传递了三个参数)。
7、关联数组(即map)
使用 declare -A 声明一个关联数组,关联数组的键是唯一的。
declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")
\# 或者
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"
7.1 获取关联数组的所有值与所有
echo "关联数组的所有值为: ${site[@]}"
8、算数运算符 expr
算数运算符使用 expr,并且运算公式被两个反引号包含。
#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
##
val=`expr $a + $b`
echo "a + b : $val"
9、关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
- 相同:
[ $a -eq $b ] - 不同:
[ $a -ne $b ] - 大于:
[ $a -gt $b ] - 小于:
[ $a -lt $b ] - 大于等于:
[ $a -ge $b ] - 小于等于:
[ $a -le $b ]
#!/bin/bash
if [ 表达式 ]
then
func1
else
func2
fi
10、布尔运算符
包括非运算、或运算、与运算。
- 非运算:
!,例如[ $a != $b ] - 或运算:
-o,例如[ $a -lt 20 -o $b -gt 100 ] - 与运算:
-a,例如[ $a -lt 20 -a $b -gt 100 ]
11、逻辑运算
如果使用逻辑运算符,条件控制应该使用双括号测试[[]]。
### condition1
if [[ $a -lt 100 && $b -gt 100 ]]
12、双括号与单括号的区别
单括号主要用于字符串比较和文件测试,而不是算术运算。
双括号用于如下几种情况:
- 1)算术运算和比较;
- 2)循环和条件控制:在双括号内,你可以使用 C 风格的 for 循环(如 for ((i=0; i<n; ++i)))、初始化变量、执行递增或递减操作等。这些功能对于控制循环和条件判断非常有用,而单括号不支持这种用法。
13、文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。具体用法是 -? filename
-d:检测文件是否是目录;-f:检测文件是否是普通文件(既不是目录,也不是设备文件);-r/w/x:检测文件是否可读/写/执行;-e:检测文件(包括目录)是否存在;-L:检测文件是否存在并且是一个符号链接;
实例:
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
14、从输入流读取,显示到输出流
read 命令从标准输入中读取一行,echo 把字符串输出到标准输出。
read name
echo "$name It is a test"
14.1 显示换行与不换行
echo 加选项 -e 表示后续字符串转义。
- 显示换行
echo -e "OK! \n" # -e 开启转义 echo "It is a test" - 显示不换行
echo -e "OK! \c" # \c 不换行 echo "It is a test" # 输出结果 OK! It is a test
14.2 显示命令执行结果
获取命令执行结果使用一对单反引号表示。如算数运算符 expr 公式被两个反引号包含。又如获取当前日期
echo `date`
15、printf 命令
printf 命令语法:
printf "format-string" [arguments...]
实例解释:%s 输出一个字符串,%ns 输出一个长度为 n 的字符串,- 表示左对齐,没有则表示右对齐。
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
16、条件控制语句
- if-else 的
[...]判断句中大于使用-gt,小于使用-lt; - if-else 的
((...))判断句中大于和小于直接使用>和<。if condition1 then command1 elif condition2 then command2 else commandn fi
17、for 循环
- 格式 1:
for var in list do command1 done - 格式 2:
for var in item1 item2 ... itemn do command1 done
18、shell 函数
18.1 函数定义与return
- 函数定义可用
[function] fun(),也可用fun()。 - return 返回值在调用该函数后通过
$?获得; - return 语句只能返回一个介于 0 到 255 之间的整数,而两个输入数字的和可能超过这个范围。要解决这个问题,使用 echo 输出。
function funWithReturn(){ echo "这个函数会对输入的两个数字进行相加运算..." echo "输入第一个数字: " read aNum echo "输入第二个数字: " read anotherNum echo "两个数字分别为 $aNum 和 $anotherNum !" return $(($aNum+$anotherNum)) } funWithReturn echo "输入的两个数字之和为 $? !"
18.2 函数参数
获取第 10 个及以上的参数,需要用 ${n} 来获取。
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
19、输入输出重定向
- 重定向 stderr 到 file:
command 2> file # 覆盖 #或者 command 2>> file # 追加 - 重定向 stdout 和 stderr 到 file:
command > file 2>&1 # 覆盖 #或者 command >> file 2>&1 # 追加 - 重定向 stdin 到 fileIn 同时重定向 stdout 到 fileOut:
command < file1 > file2 - 重定向到 /dev/null,屏蔽输出结果:
command > /dev/null # 或者屏蔽 stderr 和 stdout command > /dev/null 2>&1
20、tail 命令
tail 不加参数默认输出最后 10 行。参数含义如下:
-f:循环读取。显示文件最尾部内容,并且不断刷新;-n <+行数>:显示文件的尾部 n 行内容;若有+ln表示,从 ln 行开始至文件末尾;
21、head 命令
head 不加参数默认输出前 10 行。参数含义如下:
-n:显示文件的前 n 行内容
head -n 5 test.txt
20.1 实时输出文件的最新更新内容
tail -f test.txt
二、awk 详细梳理
基本操作:https://www.runoob.com/linux/linux-comm-awk.html
AWK 工作原理:https://www.runoob.com/w3cnote/awk-work-principle.html
AWK 数组:https://www.runoob.com/w3cnote/awk-arrays.html
2.1 常见的 awk 命令用法
- 打印满足条件的行,格式:
awk '/pattern/{print NR, $0}' file
2.2 awk 命令结构
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
其中 BEGIN 的命令与 END 的命令只运行一次。例如:
awk 'BEGIN{printf "序号\t名字\t课程\t分数\n"} {print}' marks.txt
二、牛客
参考链接:https://blog.csdn.net/qq_37085158/article/details/128360865
1、正则语法
| 表示法 | 描述 | 示例 | 备注 |
|---|---|---|---|
| . | 匹配任何字符(除了\n之外) |
b.b | b(中间任一字符)b |
| ^ | 匹配字符串起始部分 | ^Dear | 以 Dear 开头的字符串 |
| $ | 匹配字符串终止部分 | /bin/*sh$ | |||
| * | 匹配 0 次或者多次前面出现的正则表达式 | [A-Za-z0-9]* | 字母或数字出现0次或无数次 |
| + | 匹配 1 次或者多次前面出现的正则表达式 | [a-z]+.com | 字母出现一次或无数次 |
| ? | 匹配 0 次或者 1 次前面出现的正则表达式 | goo? | 不含或只含一次"goo" |
| 匹配N次前面出现的正则表达式 | [0-9] | 三位数 | |
| 匹配M~N次前面出现的正则表达式 | [0-9] | 五位到九位的数 | |
| [...] | 匹配来自字符集的任意单一字符 | [aeiou] | 元音字符集的任一字符 |
| [..x-y..] | 匹配 x~y 范围中的任意单一字符 | [0-9], [A-Za-z] | 数字或字符 |
| ^$ | 表示空行 |
2、wc 命令
wc 命令即 "Word Count",用于统计文件的字节数、单词数、行数等信息。不使用参数,wc 一词输出行数、字符数、字节数。
| 参数 | 功能 |
|---|---|
| -w | 统计单词数 |
| -c | 统计字节数 |
| -l | 统计行数 |
| -m | 统计字符数 |
| -L | 显示最长行的长度 |
3、awk 一种处理文本文件的编程语言
awk、sed、grep 并称为 Linux 系统的文本三剑客。
| 参数 | 功能 |
|---|---|
| -F | 指定输入时用到的字段分隔符 |
| -v | 自定义 |
常用的 awk 内置变量:
awk 语法由一系列条件和动作组成,在花括号内可以有多个动作,多个动作之间用分号分隔,在多个条件和动作之间可以有若干空格,也可以没有。
- 文件的一行称为一条记录,一列称为一个字段
| 内置变量名称 | 说明 |
|---|---|
| FILENAME | 当前输入文档的文件名 |
| FNR | 当前输入文档的当前行数,尤其当多个输入文档时有用 |
| FS | 设置字段分隔符,默认为空格或制表符 |
| NF | 当前行的列数,用以表示最后一个字段 |
| NR | 输入数据流的当前行号) |
3.1 仅显示指定文件中第1、2列的内容
动作是 print 条件是第 1 列,第 2 列
awk '{print $1,$2}' nowcoder.txt
3.2 以冒号为间隔符,显示指定文件中第1、2列的内容
-F 指定分隔符为 :
awk -F : '{print $1,$2}' nowcoder.txt
3.3 显示系统中所有UID号码大于500的用户信息
awk -F : '$3>=500' /etc/passwd
3.4 仅显示含有指定关键字 main 的内容
awk '/main/{print}' nowcoder.txt
3.5 以冒号为分隔符,仅显示指定文件中最后一个字段的内容
awk -F : '{print $NF}' /etc/passwd
3.6 内置函数之替换字符串子串(sub 与 gsub)
- sub(regex,sub,string):将第一次出现的子串用 regex 替换。第三个参数是可选的,默认为 $0。例如:
awk '{sub(/now/,"nowcoder"); print}' nowcoder.txt
- gsub 是 sub() 的全局替换方式
3.7 内置函数之查找位置 index
ndex函数返回子串在字符串中的第一次出现的位置。下标从1开始算起。语法格式为:index(string, substring)
awk 'BEGIN{print index("hellow", "lo")}'
3.8 内置函数之确认长度 length
length 返回字符串的字符个数,语法格式为:length(string)。
awk 'BEGIN{print length("helloworld")}'
3.9 内置函数之分割函数 split
split 函数使用有用户自定义的分割符来分割一个字符串,保存到一个数组中。如果没有提供分割符,则默认使用空格作为分割符。语法格式为:split(string, array, fieldseparator)
awk 'BEGIN{split("2013/06/16",date,"/"); print date[2],date[3]}'
4、grep 强大的文本搜索工具
grep 是全局搜索的正则表达式工具,它将搜索结果输出到屏幕。
语法格式:grep [参数] 文件...。
- 常用场景是在文件夹内搜索某字符串出现的位置,使用
grep -rnx "stringContent"
| 参数 | 功能 |
|---|---|
| -i | 忽略大小写 |
| -n | 列出所有的匹配行,显示行号 |
| -w | 匹配证词 |
| -r | 递归搜索 |
| -F | 匹配固定字符串的内容 |
| -E | 支持扩展的正则表达式 |
| -l | 只列出匹配的文件名,不列出具体的匹配行 |
| -c | 只输出匹配行的数量 |
4.1 搜索某个文件中以某个关键词开头的内容
grep ^root /etc/passwd
4.2 搜索多个文件中,包含某个关键词的内容
grep lucky /etc/passwd /etc/shadow
4.3 grep 搭配正则表达式的使用
命令格式为 grep [-cinvABC] ‘word’ filename
| 参数 | 功能 |
|---|---|
| -n | 表示输出符合要求的行及行号 |
| -v | 表示输出不符合要求的行及行号 |
4.3.1 滤出所有包含数字的行
grep '[0-9]' param.sh
如需要把行号输出,则使用 grep -n '[0-9]' param.sh
4.3.2 滤出所有不包含数字的行
grep -v '[0-9]' param.sh
5、sed 批量编辑文本文件
sed 是非交互式编辑器,它不会修改文件,除非使用 重定向保存文件或者使用 -i 选项直接修改文件内容。
默认所有行都将输出到屏幕。
sed 命令行格式为:
sed [-nefri] 'command' 输入文本
- 常用选项
| 选项参数 | 描述 |
|---|---|
| -n | 仅输出经过 sed 处理的那行 |
| -f | 直接将 sed 的动作写在文件上 |
| -i | 直接修改读取的文件内容 |
- 常用命令
| 命令参数 | 描述 |
|---|---|
| a | append 操作,追加到下一行 |
| c | 取代操作 |
| d | 后不接字符串,删除操作 |
| i | 插入操作,插入到前一行 |
| s | 取代操作,搭配正则表达式 |
| g | 行内进行全局替换 |
| p | 打印,常与 sed -n 搭配 |
- 常用参数
| 参数 | 描述 |
|---|---|
| -e | 以指定的脚本处理输入的文本文件 |
| -f | 以指定的脚本文件处理输入的文本文件 |
5.1 查找某关键字
-n 选项表示只打印符合要求的行;
/main/:正则表达式,匹配包含 main 的行;
p:打印动作命令
sed -n '/main/p' test.txt
5.2 替换关键字
-i 选项表示直接替换,不打印任何信息
s 表示替换动作;g 表示全局
sed -i 's/int/INT/g' test.txt
5.3 删除文本所有含关键字的行
-i 选项表示直接在文本里删除所有含关键字 int 的行
sed -i '/int/d' test.txt
5.4 在某行前/后插入新内容
-e 选项后跟指定处理文本的脚本,-i 表示直接在文本上操作;
4a表示在第 4 行后插入新内容,改为4i则为在第 4 行前插入新内容;
\ 表示对后面空格转义,有多少个空格插入时就有多少个空格。
sed -ie '4a\ cout << "hello world" << end;' test.txt
5.4 删除多行
sed -i '2,5d' test.txt
5.5 替换多行内容
若原先内容为:
int main
{
int a = 11;
int b = 13;
int c = 15;
return 0;
}
执行命令
sed '3,5c\ cout << "gaga"' test.txt
结果为:
int main
{
cout << "gaga"
return 0;
}
6、for 循环
6.1 带 list 的 for 循环
6.1.1 实现一:依次输出 list 的内容
for item in 1 2 3 hello world
do
echo $item
done
6.1.2 实现二:依次输出一个范围的值
for item in {1..5}
do
echo $item
done
6.1.3 实现三:设置输出的间隔值
for item in {1..5..2}
do
echo $item
done
6.1.4 实现四:输出当前目录下所有的文件和文件夹
for item in $(ls)
do
echo $item
done
6.2 不带 list 的 for 循环
for item in $@
do
echo $item
done
echo "The number of param : $#"
6.3 C 语言的 for 循环
双括号 (()) 内部可以使用C语言语法
for ((i=0;i<=10;i+=3))
do
echo $i
done
7、tr:字符转换工具
tr 命令是批量字符转换、压缩、删除的文本工具。
tr 命令从标准输入设备读取数据,经过字符串转译后,将结果输出到标准输出设备。tr 命令需要与管道符或输入重定向操作符搭配使用。
语法格式为: tr [参数] str1 str2
| 参数选项 | 描述 |
|---|---|
| -c | 反选字符串1的补集(取反) |
| -d | 删除字符串1出现的所有字符 |
| -s | 删除所有重复初夏的字符序列 |
8、xagrs:给其他命令传参数的过滤器
xargs 即 extended arguments,其功能是给其他命令传参数的过滤器。
xargs命令能够处理从标准输入或管道符输入的数据,并将其转换成命令参数;xargs命令可以将单行或多行输入的文本转换成其他格式;
常用参数:
| 参数选项 | 描述 |
|---|---|
| -n | 多行输出,常用格式 -n NumberLine |
| -d | 指定一个定界符, 常用格式 -d(char) |
| -I | 指定一个替换字符串 {} |
8.1 以多行形式输出文件内容,每行输出 2 列内容值
cat nowcoder.txt | xargs -n 2
8.2 指定定界符为x,以多行形式输出文本内容,每行显示两段内容值
echo "FirstXSecondXThirdXFourthXFifth" | xagrs -dX -n 2
9、expr 命令计数器
expt 用于在 LINUX 系统中求表达式变量的值。常用参数:
| 参数选项 | 描述 |
|---|---|
| 空格 | 隔开每个项 |
| \(反斜杠) | 放在 shell 特定的字符前面 |
| “”(引号) | 对包含空格和其他特殊字符的字符串要用引号括起来 |
9.1 使用expr进行四则运算:
expr \( 10 + 10 \) \* 2 + 100
9.2 计算字串长度
expr length "sdjf"
10、sort:对文件内容进行排序
语法格式:sort [参数] 文件。不带参数选项,默认按字母排序。
| 常用参数 | 解释 |
|---|---|
| -b | 忽略每行前面开始的空格字符 |
| -c | 检查文件是否已经按照顺序排序 |
| -d | 除字母、数字及空格字符外,忽略其他字符 |
| -m | 将几个排序好的文件进行合并 |
| -n | 按照数值的大小排序 |
| -o <输出文件> | 将排序后的结果存入指定的文件 |
| -t <分隔字符> | 指定排序时所用的栏位分隔字符 |
| -k | 指定需要排序的栏位 |
10.1 按字母顺序排序
sort fruits.txt
10.2 按数字大小排序
sort num.txt
10.3 以冒号:为间隔符,对指定文件的内容按照数字大小对第3列进行排序
cat /etc/passwd | sort -t : -k 3 -n
11、Shell 中的字符串拼接
字符串拼接方式简单,直接相连即可。例如:
name='aha'
strs="hello"
new_str=${strs}" "${name}
12、字符串截取方法总结
12.1 从左边开始截取最短匹配
# 表示截取从左边开始最短匹配,删除左边字符,保留右边字符。
* 表示匹配任意数量的任意字符。#*//表示从左边开始,找到第一个//出现的位置,删除左边,保留右边
strVal=http://www.baidu.com/123.html
echo ${char#*//}
结果为:
www.baidu.com/123.html
12.2 从左边开始截取最长匹配
## 表示截取从左边开始最长匹配,删除左边字符,保留右边字符。
strVal=http://www.baidu.com/123.html
echo ${char##*/}
结果为:
123.html
12.3 从右边开始截取最短匹配
%表示截取从右边开始最短匹配,如 %/* 表示
13、获取字符串长度的3种方法
13.1 {#str}
str="edjaopjfaopsjf"
echo ${#str}
13.2 awk 的 length 方法
length($0) 统计每行的长度
## eg1:
echo $str | awk '{print length($0)}'
## eg2:
awk '{print length($0)}' /etc/passwd
13.3 wc 的 -L 参数获取字符串长度
-L 参数对单行字符串而言,表示当前字符串的长度。对多行文件而言,表示打印最长行的长度。
echo $str | wc -L

浙公网安备 33010602011771号