一、菜鸟教程
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
- 打印满足条件的行,格式:
awk '/pattern/{print NR, $0}' file
二、牛客
参考链接: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
标签:总结,文件,shell,输出,echo,参数,字符串,专栏,awk
From: https://www.cnblogs.com/MasterBean/p/18166688