cut是/usr/bin/下的程序。
1 | cut -d. -f1 -s IPs.txt |
以上命令说的是:
-d:以.为分割。-f1:切割下来第1列。-s:以哪个文件的内容切割。
1 | mrcan@ubuntu:~$ echo 192.168.0.1 > IP.txt |
cut是/usr/bin/下的程序。
1 | cut -d. -f1 -s IPs.txt |
以上命令说的是:
-d:以.为分割。-f1:切割下来第1列。-s:以哪个文件的内容切割。1 | mrcan@ubuntu:~$ echo 192.168.0.1 > IP.txt |
Regular Expression
主要参考文档:
https://legacy.cplusplus.com/reference/regex/ECMAScript/
[[Linux_Shell编程#结合正则表达式的示例]]:case的示例中
1 | [][][]代表三个字符。 |
*、+、?、{n})量词
代表通用的信息的部分。
*:可能有(0到无数个)前导字符。*只是指示符,本身不参与,指示前面的字符会重复0到无数次。+:最少1个前导字符。?:只有1个前导字符。{n}:有n个前导字符。
{n,}:有大于等于n个的前导字符。{min,max}:至少有min个,但不超过max个(左闭右开)[])特殊模式字符
.:匹配任意单个字符[...]:匹配[]中包含的任意字符。
[1234567890]或[0-9]都表示:字符0到9[A-Z]表示大写字母[A-Za-z]表示大小写字母。\s:表示空格字符,空格、制表符都可以。(可替代[[:space:]])更多特殊字符见手册。
https://legacy.cplusplus.com/reference/regex/ECMAScript/
.*表示所有字符。
字符类
[:alpha:]:表示所有字母
grep '[[:alpha:]]' file.txt[:digit:]:表示数字[:alnum:]:表示字母+数字^[:alpha:]:表示除了字母以外
grep '[^[:alpha:]]' file.txt^、$)断言
^:出现在行首的指定字符串。
[]内外,^表达的意思是不一样的。
[]内,表示“非”[]外,才表示“首”[:alpha:]),需要放到两层[]之内,分类字符的[]之外,即:[^[:alpha:]]。$:出现在行尾的指定字符串。|)

找出带A或带B的行。
相当于求了两次grep,结果合在一起。
注意|需要转义。
组

hel{2,}o:这个匹配的是 ‘he’ + 至少2个’l’ + ‘o’, 可以匹配 “hello”, “hellllo”,但不能匹配 “hellohello” (两个hello连在一起)。(hello){2,}:这个匹配的是 "(hello)"这个整体 至少出现2次,可以匹配 “hellohello”, “hellohellohello” 等。(subpattern) 独特且强大的功能。它不仅仅是匹配,还会记住分组内匹配到的具体内容,并分配一个编号(按照左括号 ( 出现的顺序)。这些被记住的内容称为“子匹配项”或“捕获组”。(subpattern)subpattern 作为一个整体单元进行操作(特别是应用量词)。subpattern 匹配到的实际文本内容。\1, \2, \3… 来指代第1、2、3…个分组捕获的内容)。smatch[1], smatch[2])获取每个子匹配项的值。$1, $2, $3… 的语法来引用这些子匹配项。1 | 正则: (\w+)\s+\1 |
1 | 正则: (\d{4})-(\d{2})-(\d{2}) |
(?:subpattern)subpattern 作为一个整体单元进行操作(应用量词)。\n 反向引用。为什么需要它?
1 | 目标:从 "report.txt", "data.csv.zip", "image.png" 中提取扩展名 (txt, zip, png) |
1 | 匹配连续出现的 "hello" 或 "world" 两次 |

Get Regular Expression Print
*1 | echo "AAAA" > aa.txt |
1 | grep B* aa.txt |
结果:
1 | AAAA |
如上结果,因为B*代表前面的B可能会出现0到n次。所以,AAAA也匹配上了。
1 | grep BB* aa.txt |
结果:
1 | BB |
如上结果,这次没出现AAAA,因为我们限制了BB*,即第一个字符必须是B后面可能出现0到n个B。可以用B+替代上述语义:+。
因此*还是要慎用,能代表的范围太大了。
+类似于*,区别是1到n次。排除了0次的可能。
1 | grep 'B\+' aa.txt |
需要转义,并在单引号中使用。
结果:
1 | BB |
1 | echo "123.456" >> aa.txt |
怎么提取出.前后全是数字的行?
1 | grep '[0-9]\+\.[0-9]\+' aa.txt |
以上命令表示:
\.是转义,意思是中间有个..前面有最少1个0到9的字符.后面有最少1个0到9的字符结果:

需要用到{},注意在单引号中,{和}均需转义。
指示有4个A到Z字符。
1 | grep '[A-Z]\{4\}' aa.txt |
结果:AAAA
指示有大于等于2个的A到Z字符。在右括号前加,
1 | grep '[A-Z]\{3,\}' aa.txt |
结果:
1 | AAAA |
[:alpha:])注意外面还需要加一层[]
想找到文件中带数字的行:
1 | grep '[[:digit:]]' aa.txt |

想找到文件中带字母的行:

想找到文件中带字母或有0到3字符的行:

想找到文件中有非字母字符的行:

想找到文件中有非字母、非数字字符的行:

?只出现了1次前面的字符。
$以什么字符结尾。
1 | grep '[C-Z]\+$' aa.txt |
表示:结尾最少有1个C到Z的字符。
如果aa.txt的内容是:
1 | AAAA |
则执行grep '[C-Z]\+$' aa.txt的结果:

1 | grep '^[C-Z]\+$' aa.txt |
我原先想的是,这个命令表示既以至少1个C到Z的字符开头,又以至少1个C到Z的字符结尾。(错误解释!)
让Deepseek分析后,不是这样解释的。而是:
正则表达式 ^[C-Z]\+$ 要求:
因此,如果aa.txt的内容是:
1 | AAAA |
则执行grep '^[C-Z]\+$' aa.txt的结果:

^ 锚点(行首)
[C-Z] + \+ 组合
[C-Z] 只匹配 单个 C-Z 范围内的大写字母\+ 表示前面的 [C-Z] 至少出现一次(可以出现多次)[C-Z]$ 锚点(行尾)
当正则引擎执行 ^[C-Z]\+$ 时,它的匹配规则如下:
^) 开始检查第一个字符C-Z 的大写字母\+ 要求连续多个匹配,所以第二个字符必须也是 C-Z 的大写字母$)✨ 核心机制:
[C-Z]\+作为连续的整体充当了 “填充内容” 的角色,它从行首一直延伸到行尾,不允许中间插入任何非 C-Z 字符。
这种严格约束主要用于验证格式纯净的字符串,典型场景包括:
"PYTHON")"SKUXYZ")grep -x '[C-Z]\+' aa.txt (-x 表示整行匹配)Alfred Aho, Peter Weinberger, Brian Kernighan


grep是扫描每一整行的,按行为单位。而awk是按一行中的每个字段为单位查询的,类似于excel表格,可以切分各个字段。即可以按列操作。
在 awk命令中,
/tty/中的/(正斜杠) 是正则表达式(Regular Expression)的定界符。它表示中间的内容(tty)是一个需要匹配的模式。
1 | awk '/tty/{print $0}' ps.txt |

假如ps.txt文件内容如上,我们想找到字段有tty的字段。
则,在awk命令后面先用单引号' '包裹,再在里面写斜杠/ /包裹正则表达式。后半部分再用大括号{ }包裹要进行的打印操作。



ps内容:


employees文件内容:

形式:
1 | awk '$2~/^[A-z][a-z]+/ {print $1}' employees |
即,在' '内的前面加一个第几列$2和波浪号~。

第一句awk的意思是搜索每一行的所有列,查找以大写字母开头,后面至少有一个小写字母。匹配到后,打印该行的第1列。
第二句awk的意思是只搜索每一行的第2列,查找以大写字母开头,后面至少有一个小写字母。匹配到后,打印该行的第1列。
第二句awk的意思是只搜索每一行的第3列,查找以大写字母开头,后面至少有一个小写字母。匹配到后,打印该行的第1列。由于第三列全是数字,没有匹配到符合条件的行,所以打印空。
{}中对文件信息进行修改
以上语句的意思:找每一行的第1列中含Billy的,之后,把该行第1列修改为Gilly。之后,打印匹配到的所有行。
ps内容:

我们想要输出所有PID大于776的:
可以在awk后的' '单引号内写$1>776,它内置了把字符串转换为数字之后比较的操作,之后帮我们筛选出符合条件的。

甚至还可以在里面写一些简单的运算:('$1>776+1')

Stream Editor
用于处理流。把字符串、文件按流的方式处理。流的特点是只能单向,不能后撤。