正则表达式学习
正则表达式:是处理字符串的⼀种表达⽅式。提供了⼀种从⼀组字符串中
选择特定字符串的机制
POSIX
规范定义了UNIX
操作系统应当⽀持的功能,POSIX
规范的正则表达式:
BRE
:(Basic Regular Expression
)基本型正则表达式ERE
:(Extended Regular Express
)扩展型正则表达式
BRE
和ERE
⼆者的区别,简单的说就在于(
、)
、{
、}
、+
、?
、|
这7
个特殊字符的使⽤⽅法上:
- 在
BRE
中,如果想要这些字符表示特殊的含义,就需要把它们转义。元字符(
、)
、{
、}
、+
、?
、|
必须转义之后才具有特殊含义,如\+
、\?
、\|
,⽽且也⽀持\1
、\2
之类反向引⽤- 反之,在
ERE
中,如果要这些字符不表示特殊的含义,就需要把它们转义。虽然BRE
名为“基本”⽽ERE
名为“扩展”,但ERE
并不要求兼容BRE
的语法,⽽是⾃成⼀体BRE
中的特殊字符:.
、\
、[
、^
、$
、*
ERE
中的特殊字符多了7
个,即:.
、\
、[
、^
、$
、*
、(
、)
、{
、}
、+
、?
、|
正则表达式与通配符没有任何关系,不是包含关系
- 通配符,是
Shell
提供的功能- 正则表达式只是⽤来处理字符串
如何学习正则表达式?
- 背,一些特殊字符的意义
- 实际练习
案例:
⼀个常⻅的正则表达式
^1[3-9](\d{9})$
^
:锚点操作符,匹配字符串的开头[3-9]
:列表操作符,只匹配中括号中的⼀个字符。-
:范围操作符指定范围\d
:代表0-9
数字{9}
:间隔运算符,匹配前⼀个元素⼏次(\d{9})
:分组/捕获组,定义⼀个⼦表达式$
:锚点操作符,匹配字符串的结尾
特殊符号的意义
直抒胸臆操作符:
类别 匹配类型 匹配字符 Cat
字符串 Cat
,属于串联Cat
,不能匹配Catt
C
字符 C
C
渣男操作符:
类别 匹配类型 匹配字符 .
匹配所有的字符,除了 newline
和null
通吃 lsp
重复操作符:
类别 匹配类型 *
匹配前⼀个元素 0
次或多次+
匹配前⼀个元素 1
次或多次?
匹配前⼀个元素 0
次或1
次
间隔操作符 { ... }:
类别 匹配类型 {count}
匹配前⼀个元素 count
次{min,}
匹配前⼀个元素⾄少 min
次{min, max}
匹配前⼀个元素⾄少 min
次,⾄多max
次
备胎操作符:
类别 匹配类型 匹配字符 |
匹配前⼀个表达式或后⼀个表达式 在吗?我怀孕了
列表操作符 [ ... ] and [^ ... ] :
⼀般操作符在列表操作符⾥会失去特殊意义,除了:
类别 匹配类型 ]
结束列表, []]
\
转义字符 [:
字符类别操作符开始 :]
字符类别操作符结束 -
范围操作符, 0-9
字符类别操作符 [: ... :] :
类别 匹配类型 匹配字符 [:alnum:]
[A-Za-z0-9]
数字和字⺟字符 [:alpha:]
[A-Za-z]
字⺟字符 [:blank:]
[ \t]
空格和 TAB
[:cntrl:]
[\x00-\x1F\x7F]
控制符 [:digit:]
[0-9]
数字 [:graph:]
[\x21-\x7E]
可视字符 [:lower:]
[a-z]
⼩写字⺟字符 [:print:]
[\x20-\x7E]
可视字符和空格( ASCII
,040-0176
)[:punct:]
][!"#$%&'()*+,./:;<=>?@\^_`{|}~-]
标点符号 [:space:]
[\t\r\n\v\f]
空⽩字符 [:upper:]
[A-Z]
⼤写字⺟字符 [:xdigit:]
[A-Fa-f0-9]
⼗六进制字符
特殊字符类别操作符:
类别 匹配类型 匹配字符 \w
[:alnum:]
数字和字⺟字符 \d
[:digit:]
数字 \W
[^[:alnum:]]
除了数字和字⺟字符 \B
[^[:digit:]]
除了数字 \<
^
匹配字符串的开头 \>
$
匹配字符串的结尾 \b
to\b
匹配to!
,但不匹配tomorrow
匹配单词边界字符
范围操作符:
类别 匹配类型 -
匹配指定范围,但是需在列表中使⽤,并指定范围,如 [a-z]
。[-az]
或者[az-]
表示匹配字⺟a
和z
还有-
锚点操作符:
类别 匹配类型 ^
匹配字符串的开头,需在开头 $
匹配字符串的结尾或者换⾏符的前⼀个位置,需在结尾
- 如果
^
在列表操作符中使⽤,并且在⾸位,代表取反
操作符优先级:
优先级(由⾼到低) 操作符 归类相关的括号符号 [::]
转义字符 \<特殊字符>
括号表达 []
分组 ()
单字符重复 * + ?{m, n}
串联 .
锚点 ^ $
备选 |
基础示例
grep
-v
:逆转显示-i
:忽略⼤⼩写-A
:向上显示⼏⾏-B
:向下显示⼏⾏-E
:启⽤扩展—color
:显示颜⾊
egrep
- 使用
grep -E
,启用ERE
扩展型正则表达式
案例:
打开
test.swift
文件,写入以下文本:struct LGTeacher { let name: String let class: String let credit:String let description: String } struct LGTeachers { let name: String let class: String let credit:String let description: String } extension LGTeacher { static var all: [LGTeacher] { [ LGTeacher( name: "Cooci", license: "http://creativecommons.org/licenses/by-sa/3.0", credit: "http://commons.wikimedia.org/wiki/User:Lin%C3%A91", description: "Basil is commonly used fresh in cooked recipes. In general, it is added at the last moment, as cooking quickly destroys the flavor. The fresh herb can be kept for a short time in plastic bags in the refrigerator, or for a longer period in the freezer, after being blanched quickly in boiling water. The dried herb also loses most of its flavor, and what little flavor remains tastes very different.9oo *oo" ), LGTeacher( name: "Kody", license: "http://creativecommons.org/licenses/by-sa/3.0", credit: "http://commons.wikimedia.org/wiki/User:Lin%C3%A91", description: "Saffron's aroma is often described by connoisseurs as reminiscent of metallic honey with grassy or hay-like notes, while its taste has also been noted as hay-like and sweet. Saffron also contributes a luminous yellow-orange colouring to foods. Saffron is widely used in Indian, Persian, European, Arab, and Turkish cuisines. Confectioneries and liquors also often include saffron." ), LGTeacher( name: "Hank", license: "http://creativecommons.org/licenses/by-sa/3.0", credit: "http://commons.wikimedia.org/wiki/User:Raul654", description: "Marjoram is used for seasoning soups, stews, dressings and sauce. Majorana has been scientifically proved to be beneficial in the treatment of gastric ulcer, hyperlipidemia and diabetes. Majorana hortensis herb has been used in the traditional Austrian medicine for treatment of disorders of the gastrointestinal tract and infections." ), LGTeacher( name: "CC", license: "http://www.gnu.org/licenses/old-licenses/fdl-1.2.html", credit: "http://commons.wikimedia.org/wiki/User:Fir0002", description: "The leaves, both fresh and dried, are used in traditional Italian cuisine. They have a bitter, astringent taste and are highly aromatic, which complements a wide variety of foods. Herbal tea can be made from the leaves. When burnt, they give off a mustard-like smell and a smell similar to burning wood, which can be used to flavor foods while barbecuing. Rosemary is high in iron, calcium and vitamin B6.") , LGTeacher( name: "Cat", license: "http://commons.wikimedia.org/wiki/File:AniseSeeds.jpg", credit: "http://commons.wikimedia.org/wiki/User:Ben_pcc", description: "Anise is sweet and very aromatic, distinguished by its characteristic flavor. The seeds, whole or ground, are used in a wide variety of regional and ethnic confectioneries, including black jelly beans, British aniseed balls, Australian humbugs, and others. The Ancient Romans often served spiced cakes with aniseseed, called mustaceoe at the end of feasts as a digestive. " ) ] } }
匹配包含
LG
的内容grep "LG" test.swift ------------------------- struct LGTeacher { struct LGTeachers { extension LGTeacher { static var all: [LGTeacher] { [ LGTeacher( LGTeacher( LGTeacher( LGTeacher( LGTeacher(
匹配包含
LG
的内容,将每一行的匹配结果,都向下多显示一行grep "LG" test.swift -A 1 ------------------------- struct LGTeacher { let name: String -- struct LGTeachers { let name: String -- extension LGTeacher { static var all: [LGTeacher] { [ LGTeacher( name: "Cooci", -- LGTeacher( name: "Kody", -- LGTeacher( name: "Hank", -- LGTeacher( name: "CC", -- LGTeacher( name: "Cat",
匹配包含
LG
的内容,将每一行的匹配结果,上下各多显示一行grep "LG" test.swift -A 1 -B 1 ------------------------- struct LGTeacher { let name: String -- -- struct LGTeachers { let name: String -- -- extension LGTeacher { static var all: [LGTeacher] { [ LGTeacher( name: "Cooci", -- -- ), LGTeacher( name: "Kody", -- -- ), LGTeacher( name: "Hank", -- -- ), LGTeacher( name: "CC", -- -- , LGTeacher( name: "Cat",
匹配包含
lgteacher
的内容,忽略大小写grep "lgteacher" test.swift -i ------------------------- struct LGTeacher { struct LGTeachers { extension LGTeacher { static var all: [LGTeacher] { [ LGTeacher( LGTeacher( LGTeacher( LGTeacher( LGTeacher(
匹配过滤
LGTeacher
后的内容grep "LGTeacher" test.swift -v
匹配包含
LGTeacher
的内容,但不匹配LGTeachers
grep "LGTeacher[^s]" test.swift ------------------------- struct LGTeacher { extension LGTeacher { static var all: [LGTeacher] { [ LGTeacher( LGTeacher( LGTeacher( LGTeacher( LGTeacher(
匹配包含
oo
的内容grep "oo" test.swift
匹配包含
oo
的内容,过滤前面由小写字母开头的内容grep "[^a-z]oo" test.swift //或者 grep "[^[:lower:]]oo" test.swift
匹配包含
oo
的内容,只保留数字或符号开头的内容grep "[^A-Za-z]oo" test.swift
匹配包含
oo
的内容,只保留数字开头的内容grep "[0-9]oo" test.swift //或者 grep "\doo" test.swift
匹配包含
oo
的内容,只保留符号开头的内容grep "[^A-Za-z0-9]oo" test.swift //或者 grep "\Woo" test.swift
匹配包含
oo
的内容,过滤前面由符号开头的内容grep "[A-Za-z0-9]oo" test.swift //或者 grep "\woo" test.swift
使用
.
占中间两位,匹配C
开头,ci
结尾的内容grep "C..ci" test.swift ------------------------- name: "Cooci",
匹配
C
开头,使用.
占后两位的内容grep "C.." test.swift
.
:匹配所有的字符,除了newline
和null
匹配
Co
开头,使用*
占后一位的内容grep "Co*" test.swift
*
:匹配前⼀个元素0
次或多次
匹配
Coo
开头,使用*
占后一位的内容grep "Coo*" test.swift
匹配
C
开头,后面接两个o
的内容grep -E "Co{2}" test.swift ------------------------- name: "Cooci",
- 间隔操作符
{ ... }
,是ERE
中支持的特殊符号。grep
命令支持ERE
表达式,需要增加-E
参数
分组与向后引⽤
分组\捕获组操作符
(( ... ) or \( ... \))
:
- 定义⼀个⼦表达式。正则表达式将此序列视为⼀个单元。圆括号在整体匹配完后进⾏匹配
- 可以配合反向引⽤操作符,重复使⽤分组匹配的结果
反向引⽤操作符
(\digit)
:
- 反向引⽤操作符由
\数字
表示,数字需介于1-9
,代表引⽤那个分组的匹配结果
案例1:
匹配包含
oo
的内容,只保留数字开头的内容,使用(\d)
进行分组grep -E "(\d)oo" test.swift
- 分组
( ... )
,是ERE
中支持的特殊符号。grep
命令支持ERE
表达式,需要增加-E
参数
案例2:
通过
\1
获取第一个分组内容grep -E "description(.*)(\1)" test.swift
- 反向引⽤操作符
(\digit)
,代表引⽤那个分组的匹配结果
\ 字符
以下内容在部分语⾔中不⽀持
每种环境,⽆论是
Python
、Perl
、Java
、C#
、Ruby
还是其他,在实现正则表达式时都有特殊的差别。Swift
也不例外
Objective-C
和Swift
都要求您转义⽂字字符串中的特殊字符(即,在它们
前⾯加反斜杠\
字符)。反斜杠本身就是这样的特殊字符之⼀。由于⽤于创建
正则表达式的模式也是字符串,因此会增加复杂性,因为在使⽤Stringand
时
需要转义反斜杠字符NSRegularExpression
这意味着标准正则表达式
\.
将出现\\.
在您的Swift
(或Objective-C
)代码中
- ⽂字
\\.
定义了⼀个类似于以下字符串:\.
- 正则表达式
\.
然后将匹配单个句点字符
贪婪模式
贪婪模式、勉强模式与侵占模式:
贪婪匹配 勉强匹配 侵占匹配 作⽤ X?
X??
X?+
匹配 X
零次或⼀次X*
X*?
X*+
匹配 X
零次或多次X+
X+?
X++
匹配 X
⼀次或多次X{n}
X{n}?
X{n}+
匹配 X
,n
次X{n,}
X{n,}?
X{n,}+
匹配 X
⾄少n
次X{n,m}
X{n,m}?
X{n,m}+
匹配 X
⾄少n
次,但不多于m
次
案例1:
匹配
test.swift
文件中,description
相关内容
grep "description.*\"$" test.swift //或者 grep -E "description(.*)[\"]$" test.swift
案例2:
假定要分析的字符串是
xfooxxxxxxfoo
模式
.*foo
(贪婪模式)由两部分
p1
:(.*)
p2
:(foo)
查看匹配结果,其中
p1
中的匹配⽅式使⽤默认⽅式(贪婪型)
- 第⼀轮:匹配开始时,
p1
匹配所有字符xfooxxxxxx
,匹配成功,但p2
⽆匹配字符,本轮匹配失败- 第⼆轮:减少
p1
部分的匹配量,留出最后⼀个字符, 此时存在两个字符串,s1
代表xfooxxxxxxfo
和s2
代表o
。s1
匹配p1
, 但s2
不匹配p2
。本轮匹配失败- 第三轮,继续减少
p1
匹配量,留出两个字符, 字符串被分割成xfooxxxxxxfo
和oo
两部分。结果同上- 第四轮,再次减少
p1
匹配量,字符串分割成xfooxxxxxx
和foo
两个部分,这次p1/p2
同时匹配。返回匹配成功
案例3:
模式
.*?foo
(勉强模式)最⼩匹配⽅式
p1
:(.*?)
p2
:(foo)
查看匹配结果,其中
p1
中的匹配⽅式使⽤勉强模式匹配
- 第⼀轮:
p1
由于是0
或任意次,⾸先匹配0
次。所以直接⽤字符串去匹配p2
,但p2
⽆匹配字符,本轮匹配失败- 第⼆轮:增加
p1
部分的匹配量,匹配x
。此时存在两个字符串,s1
代表x
和s2
代表fooxxxxxxfoo
。s1
匹配p1
, 但s2
不匹配p2
。本轮匹配失败;继续上述匹配直到满⾜p2
案例4:
模式
.*+foo
(侵占模式)
p1
:(.*+)
p2
:(foo)
查看匹配结果,其中
p1
中的匹配⽅式使⽤侵占模式匹配
- 匹配开始时读⼊所有字符串,和
p1
匹配成功,但没有剩余字符串去和p2
匹配。匹配失败
简单地说,贪婪模式和侵占模式相⽐,贪婪模式会在只有部分匹配成功的条件下,依次从多到少减少匹配成功部分模式的匹配数量,将字符留给模式其他部分去匹配。⽽侵占模式则是占有所有能匹配成功部分,绝不留给其他部分使⽤
案例5:
使用
(fooq|foo)*(qbarquux|bar)
完全匹配的字符串是?
A
、fooqbarquuxB
、fooqbarC
、以上都选仅选项
B
可以完全匹配,选项A
只能匹配出fooqbar
前半部分
案例6:
使用
((a*)b)*\1\2
完全匹配的字符串是?
A
、aabababaB
、aabaabaabaabaaC
、以上都选答案为选项
C
,选项A
和B
都可以完全匹配
- 如果分组不⽌⼀次匹配(例如,如果后⾯跟着重复运算符),则
向后引⽤将匹配分组最后匹配的⼦字符串
案例7:
使用
(one(x)|two(y))-and-(three\2|four\3)
完全匹配的字符串是?
A
、onex-and-threexB
、twoy-and-fouryC
、onex-and-fourD
、twoy-and-threeyE
、twoy-and-threex选项
A
和B
都可以完全匹配
- 分组
\2
、\3
分别对应(x)
、(y)
,当(x)
匹配失败,分组\2
的位置存在,但分组报错- 当访问报错的分组,匹配将会中断
案例8:
在
t.swift
文件中,删除description
节点
使用
description:(\W)(.*)
将匹配的内容替换为空
结尾的渣男操作符
.
,除newline
和null
匹配所有字符
案例9:
将
license
和credit
的值,都改为https://www.baidu.com/
使用
(license|credit):[\W](.)*
将匹配的内容替换为$1: "https://www.baidu.com/",
$1
表示分组\1
的(license|credit)
更⾼级的⽤法
零宽断⾔
断⾔:在指定位置应该满⾜⼀定的条件
当捕获组以开头时
?=
,表示该组将被⽤作零宽度正预测先⾏断⾔,仅当前⼀个模式与捕获组中的模式相匹配时才与前⼀个模式匹配。例如,A(?=B)
与A
匹配,并且⻢上跟着B
。可以匹配AB
、ABB
、ACB
Unicode
匹配特定类别的
Unicode
字符\p{ ... }
:
\p{L}
所有字符,\p{Lu}
所有⼩写字符,\p{N}
\P{}
匹配不特定类别的Unicode
字符
sed命令
sed
命令:可以将数据进⾏替换、删除、新增、选取特定内容等功能,⽤作⼀整⾏字符处理
命令格式
sed [options] 'command' file(s) sed [options] -f scriptfile file(s)
选项
-e<script>或--expression=<script>:以选项中的指定的script来处理输入的文本文件; -f<script文件>或--file=<script文件>:以选项中指定的script文件来处理输入的文本文件; -h或--help:显示帮助; -n或--quiet或——silent:仅显示script处理后的结果; -V或--version:显示版本信息。
参数
文件:指定待处理的文本文件列表
sed命令
a\ # 在当前行下面插入文本。 i\ # 在当前行上面插入文本。 c\ # 把选定的行改为新的文本。 d # 删除,删除选择的行。 D # 删除模板块的第一行。 s # 替换指定字符 h # 拷贝模板块的内容到内存中的缓冲区。 H # 追加模板块的内容到内存中的缓冲区。 g # 获得内存缓冲区的内容,并替代当前模板块中的文本。 G # 获得内存缓冲区的内容,并追加到当前模板块文本的后面。 l # 列表不能打印字符的清单。 n # 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。 N # 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。 p # 打印模板块的行。 P # (大写) 打印模板块的第一行。 q # 退出Sed。 b lable # 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。 r file # 从file中读行。 t label # if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。 T label # 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。 w file # 写并追加模板块到file末尾。 W file # 写并追加模板块的第一行到file末尾。 ! # 表示后面的命令对所有没有被选定的行发生作用。 = # 打印当前行号码。 # # 把注释扩展到下一个换行符以前。
sed替换标记
g # 表示行内全面替换。 p # 表示打印行。 w # 表示把行写入一个文件。 x # 表示互换模板块中的文本和缓冲区中的文本。 y # 表示把一个字符翻译为另外的字符(但是不用于正则表达式) \1 # 子串匹配标记 & # 已匹配字符串标记
sed元字符集
^ # 匹配行开始,如:/^sed/匹配所有以sed开头的行。 $ # 匹配行结束,如:/sed$/匹配所有以sed结尾的行。 . # 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。 * # 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。 [] # 匹配一个指定范围内的字符,如/[sS]ed/匹配sed和Sed。 [^] # 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。 \(..\) # 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。 & # 保存搜索字符用来替换其他字符,如s/love/ **&** /,love这成 **love** 。 \< # 匹配单词的开始,如:/\<love/匹配包含以love开头的单词的行。 \> # 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。 x\{m\} # 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。 x\{m,\} # 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。 x\{m,n\} # 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。
参考文档:sed命令
awk命令
awk
命令:⽐sed
更精准,通常将⼀⾏在切割成相应的字段,再去处理
命令格式
awk [options] 'script' var=value file(s) awk [options] -f scriptfile var=value file(s)
选项
-F fs fs指定输入分隔符,fs可以是字符串或正则表达式,如-F: -v var=value 赋值一个用户定义变量,将外部变量传递给awk -f scripfile 从脚本文件中读取awk命令 -m[fr] val 对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
awk
脚本是由模式和操作组成的模式可以是以下任意一个:
- /正则表达式/:使用通配符的扩展集
- 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试
- 模式匹配表达式:用运算符
~
(匹配)和!~
(不匹配)BEGIN
语句块、pattern
语句块、END
语句块操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内,主要部分是:
- 变量或数组赋值
- 输出命令
- 内置函数
- 控制流语句
awk
脚本基本结构awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file
一个
awk
脚本通常由:BEGIN
语句块、能够使用模式匹配的通用语句块、END
语句块三部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,脚本通常是被单引号
或双引号
中awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename awk "BEGIN{ i=0 } { i++ } END{ print i }" filename
awk
的工作原理awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
- 第一步:执行
BEGIN{ commands }
语句块中的语句- 第二步:从文件或标准输入
(stdin)
读取一行,然后执行pattern{ commands }
语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕- 第三步:当读至输入流末尾时,执行
END{ commands }
语句块
案例1:
echo -e "A line 1\nA line 2" | awk 'BEGIN{ print "Start" } { print } END{ print "End" }' Start A line 1 A line 2 End
BEGIN
语句块在awk
开始从输入流中读取行之前
被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN
语句块中END
语句块在awk
从输入流中读取完所有的行之后
即被执行,比如打印所有行的分析结果这类信息汇总都是在END
语句块中完成,它也是一个可选语句块pattern
语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern
语句块,则默认执行{ print }
,即打印每一个读取到的行,awk
读取的每一行都会执行该语句块
案例2:
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3; }' v1 v2 v3
- 当使用不带参数的
awk
的
案例3:
双引号拼接使用
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"="var2"="var3; }' v1=v2=v3
{ }
类似一个循环体,会对文件中的每一行进行迭代,通常变量初始化语句(如:i=0
)以及打印文件头部的语句放入BEGIN
语句块中,将打印的结果等语句放在END
语句块中
参考文档:awk命令
lldb使⽤正则对指定代码添加断点
对符合正则表达式的符号下断点
breakpoint set --func-regex=[regular-expression]
对指定库中的符合正则表达式的符号下断点
breakpoint set --func-regex=[regular-expression] --shlib=libfoo.dylib
通过对指定的正则表达式对⽂件内容设置断点
breakpoint set --source-pattern-regexp [regular-expression] --file [SourceFile]
案例
在
Block
源码中,搜索block
、copy
相关的代码使用
(.*)[B|b]lock(.*)[C|c]opy(.*)
匹配相关代码
使用命令对符合正则的符号下断点
breakpoint set --func-regex=(.*)[B|b]lock(.*)[C|c]opy(.*)
- 共设置
1990
处断点使用
br
、-r
等缩写形式br set -r (.*)[B|b]lock(.*)[C|c]opy(.*)
- 使用长参数
--func-regex
,后面的值可以用等号或空格设置- 使用短参数
-r
,后面的值只能用空格设置更简单的缩写:
rb
命令rb (.*)[B|b]lock(.*)[C|c]opy(.*)
查看
rb
命令help rb ------------------------- 'rb' is an abbreviation for 'breakpoint set -r %1'
指定在动态库
libsystem_blocks.dylib
中设置断点rb (.*)[B|b]lock(.*)[C|c]opy(.*) --shlib=libsystem_blocks.dylib
- 断点设置的范围缩小,共设置
3
处断点使用
-s
缩写参数rb (.*)[B|b]lock(.*)[C|c]opy(.*) -s libsystem_blocks.dylib
对指定⽂件内容设置断点
br set --source-pattern-regexp (.*)[B|b]lock(.*)[C|c]opy(.*) --file runtime.cpp
使用
-p
、-f
等缩写参数br set -p (.*)[B|b]lock(.*)[C|c]opy(.*) -f runtime.cpp
自定义简写命令
使用
command alias
命令,为br set -p
创建简写命令command alias pb br set -p %1 -f %2 ------------------------- error: 'br' is not an existing command.
br
命令已经是breakpoint
的简写形式,这里必须对breakpoint
命令进行设置command alias pb breakpoint set -p %1 -f %2
设置成功后,可以直接使用简写命令
pb (.*)[B|b]lock(.*)[C|c]opy(.*) runtime.cpp
查看
pb
命令help pb ------------------------- 'pb' is an abbreviation for 'breakpoint set -p %1 -f %2'
在
lldb
中设置的简写命令,仅在本次调试中有效