什么是正则表达式?

正则表达式是一种功能强大、灵活性高的模式匹配工具。它可以进行更复杂的模式匹配,包括字符的重复、选择、分组、反向引用等。在Linux系统使用过程中, 有时会把它和通配符(wildcards)弄混淆.

通配符是一种特殊字符或字符序列,用于在文件名匹配和搜索中代表其他字符或字符序列。通配符可以替代一个或多个字符,以便匹配符合特定模式的文件名或文本字符串。它的形式与正则表达式非常相似, 但逻辑有所不同: 通配符的执行通常由操作系统或特定工具处理,其匹配逻辑可能是基于简单的字符串匹配算法。而正则表达式通常由正则表达式引擎执行,这些引擎会使用更复杂的算法和技术来实现正则表达式的模式匹配,如NFA(非确定有限自动机)或DFA(确定有限自动机)。

以下是一些常见的通配符:

  1. “[]“(范围通配符):用于指定一个字符范围。例如,”[a-z]“ 可以匹配任何小写字母字符,”[0-9]” 可以匹配任何数字字符。
  2. “[!]”(否定通配符):用于排除特定字符。例如,”[!a-z]” 可以匹配任何非小写字母字符,”[!0-9]” 可以匹配任何非数字字符。
  3. “{,}”(集合通配符):用于指定多个选项。例如,”{cat,dog}” 可以匹配 “cat” 或 “dog”。
    • 集合通配符中的值可以没有,表示为空. 但值之间需用逗号分隔. 且逗号前后不能有空格, 否则拓展失效(因为是直接在bash中运行, 空格是分割符).
    • 不是文件拓展(如*, []等), 不管文件存在与否都拓展成给定值. 对于文件拓展, 当你按下tab时, 它会自动搜索匹配的文件, 并将所有匹配到文件直接原位置展开, 以空格分割.
    • 优先级高,总是先被运行(相较于其他拓展)
    • 可以嵌套拓展
      • {A{1,2},B{1,2}}: 等于A1 A2 B1 B2
    • {Start..End}: 与方括号类似,不过用”..”连接
    • {Start..End..Step}: 指定步长
  4. “()”(分组通配符):用于将多个字符组合在一起以进行更复杂的匹配。例如,”(ab)+” 可以匹配连续出现的 “ab”。
  5. “*“(星号):匹配任意字符序列(包括空字符序列)。例如,”*.txt” 可以匹配所有以 “.txt” 结尾的文件名,如 “file.txt”、”document.txt” 等。在正则表达式中这通常表示匹配前面的字符0次或多次.
    • “*/“再加上通配符可以匹配子目录,有几层子目录就写几层
    • “**/“可以匹配零个或者多个子目录
  6. “?”: 匹配任意单个字符.

使用通配符能够让你在处理多个文件作为输入或是批量查看文件时提高效率, 然而它的重心在于”文件”, 而非专门的”文本”, 这也是为什么不将单列为一节. 要对文本进行处理, 还得看我Regex.

正则表达式有哪些类型?

或许你使用过多种语言, 也使用过他们提供的正则表达式工具, 那么你就会发现尽管大体相似, 但似乎每个语言的正则表达式都不尽相同. 通常我们将正则表达式分为三类, BRE, ERE, Perl正则.

BRE(Basic Regular Expressions):BRE是一种比ERE更简单的正则表达式语法,支持较少的元字符和操作符,但仍可以满足基本的模式匹配需求。它主要被诸如grep、sed和awk等POSIX工具使用.

ERE(Extended Regular Expressions):ERE是一种比BRE更强大的正则表达式语法,支持更多的元字符和操作符,如重复次数限定符(+、*、?等)、分组、反向引用等。Perl, Python, PHP中均用到了ERE, 需要注意的是 Python的re模块要使用ERE语法,需要通过指定标志参数(如re.VERBOSE)启用ERE语法。

Perl正则表达式(Perl-regex):Perl正则表达式是一种高度灵活和功能强大的正则表达式语法,扩展了ERE和BRE的功能,并添加了许多Perl特定的功能和语法。它主要在Perl编程语言中使用,但也在其他编程语言中得到了应用, 如JavaScript:JavaScript的正则表达式语法受到Perl正则表达式的影响,例如,使用(?:…)进行非捕获分组,使用\1、\2等进行反向引用。R与python默认使用的就是perl正则表达式语法.

从BRE到ERE再到Perl-regex, 其拥有的高级特性越来越多. 然而直接列出每个正则的语法对我们使用他们没有任何帮助, 故而我接下来会逐点介绍他们的异同之处.

不同Regex语法的相同之处

“[:alnum:]”,”[:alpha:]”,”[:digit:]”,”[:lower:]”,”[:upper:]”,”[:space:]”,”[:blank:]”,”[:graph:]”,”[:print:]”,”[:cntrl:]”,”[:punct:]”,”[:xdigit:]”,”[0-9]”,”[xyz]”,”[\^xyz]”,”[A-Za-z]”,”[\^A-Za-z]”,”*“,”\W”,”\w”,”\B”,”\b”,”\\“

以上字符在各个Regex语法中 用法,功能都一致, 我们也可以将其称之为基础功能. 但需要注意的是形如[:alnum:]的正则符和通配符中的保持一致, 但真正使用时, 我们需要将其用[]再包起来, 而通配符和JavaScript的RegExp对象则不需要.

相同Regex符号的不同之处

  • 单词边界: 除\b外, 还有两个符号可以匹配边界,\<,\>. 其中\<匹配左边界,\>匹配右边界. 然而后者仅仅在BRE和ERE中支持, Perl-regex无法使用.
  • (): ()是一个极其重要的符号, 它可以: 1) 将一部分正则表达式视为一个整体,形成一个分组, 从而能对这个分组进行整体操作; 2) 构建子表达式,用于定义复杂的模式。这允许你组合和嵌套多个子表达式,以构建更复杂的模式匹配规则; 3) 捕获匹配的文本。匹配成功后,捕获组会记录匹配的文本,以便后续处理和引用。可以通过编号或命名来引用捕获组, 实现重复出现相同模式的匹配,或者进行替换操作。在ERE和Perl-regex中, 可以直接使用, 但在BRE中需要对括号进行转义(这是BRE使用高级功能的办法, 为了后续说明简单, 若需要进行转义则表述为转义使用).
  • ?: 匹配前面的子表达式 0 次或 1 次(等价于{0,1}). 只有BRE需要转义使用.
  • +: 匹配前面的子表达式 1 次或多次(等价于{1, }). 只有BRE需要转义使用.
  • {n},{n,}{n,m}: 匹配n次/大于n次/n到m次. BRE需要对{}进行转义(即\{\})
  • .: 匹配除换行符(’\n’)之外的任意单个字符. 如果要匹配包括“\n”在内的任何一个字符,请使用:’(^$)|(.)‘ (对于ERE), ‘[.\n]‘ (对于Perl-regex). 对于BRE, awk中句点能匹配换行符.
  • \num: 匹配 num,其中 num是一个正整数。表示对所获取的匹配的引用. BRE不支持.

有哪些文本处理工具?

文本处理最常用的三个命令行工具被我们称之为”linux三剑客”, 它们是:

  1. grep:grep 是 “Global Regular Expression Print” 的缩写,用于在文件中搜索匹配指定模式的文本行。它支持使用正则表达式进行强大的模式匹配,并可以递归搜索子目录。

  2. sed:sed 是 “Stream Editor” 的缩写,它是一个流式文本编辑器,用于对文本进行流式处理。它主要用于在文本流中匹配和替换模式,并支持正则表达式、行选择、行删除、行插入等功能。

  3. awk:awk 是一种强大的文本处理工具,用于从结构化文本文件中提取和操作数据。它支持灵活的模式匹配和处理,具有强大的文本处理能力和内置函数,可以进行数据过滤、转换、计算和格式化等操作。

好像讲了, 又好像什么都没讲, 只知道用处不知道用法学了等于没学. 这三个命令各有所长, 接下来将逐一介绍.

Grep命令:

控制匹配格式:

  • -i--ignore-case):
    • 忽略大小写进行匹配。 例如:grep -i "hello" file.txt
  • -e pattern--regexp=pattern):指定一个模式进行搜索匹配。
    • 例如:grep -e "pattern1" -e "pattern2" file.txt
  • -v--invert-match):
    • 反转匹配,只显示不匹配的行。 例如:grep -v "error" file.txt
  • -w--word-regexp):仅匹配完整的单词,而不是部分匹配。
    • 例如:grep -w "word" file.txt
  • -x--line-regexp):只匹配整行,而不是行中的部分内容。
    • 例如:grep -x "exact line" file.txt
    • 事实上等同于^pattern$
  • -w (--word-regexp) : 只显示全字符合的列。
  • -f file--file=file):从指定文件中读取模式,逐行搜索匹配。
    • 例如:grep -f patterns.txt file.txt

选择不同的正则表达式语法:

  • -E--extended-regexp):使用扩展的正则表达式语法ERE。
    • 例如:grep -E "pattern" file.txt
    • 等同于egrep "pattern" file.txe
  • -P--perl-regexp):使用 Perl 兼容的正则表达式语法Perl-regex。
    • 例如:grep -P "pattern" file.txt
  • -F--fixed-strings):按照字符串字面值进行匹配,而不是正则表达式。
    • 例如:grep -F "string" file.txt
  • -G (--basic-regexp) : 默认情况下,grep 命令使用基本正则表达式进行匹配,因此可以省略 -G 参数。

控制匹配的文件

  • -x--exclude=file):指定要排除的文件模式。
    • 例如:grep "pattern" --exclude="*.log" directory
    • 其他用法同下;
  • --include=file:指定要包含的文件模式。
    • 例如:grep "pattern" --include="*.txt" directory
    • 多个文件:使用逗号分隔多个要包含的文件模式。例如:--include=*.txt,*.log
    • 通配符模式:使用通配符模式指定要包含的文件。例如:--include=prefix*
    • 文件路径:使用相对或绝对文件路径指定要包含的文件。例如:--include=/path/to/included/file.txt
  • -r 参数同样会递归搜索指定目录及其所有子目录中的文件内容,但不会包括符号链接所指向的目录。当遇到符号链接时,它会忽略链接所指向的目录,而不会进一步递归搜索。
    • 例如:grep -r "pattern" directory
    • -R 参数会递归搜索指定目录及其所有子目录中的文件内容,包括符号链接所指向的目录。它会遍历整个目录树来搜索匹配的文件内容。
  • --exclude-dir=dir:排除指定目录的搜索。该选项只适用于递归搜索,并且排除的目录将被完全忽略,不会搜索其下的任何文件或子目录。
    • 例如:grep "pattern" --exclude-dir=docs directory
    • 单个目录:指定要排除的单个目录的名称。例如:--exclude-dir=logs
    • 多个目录:使用逗号分隔多个要排除的目录名称。例如:--exclude-dir=logs,cache
    • 通配符模式:使用通配符模式指定要排除的目录。例如:--exclude-dir=docs*
    • 目录路径:使用相对或绝对目录路径指定要排除的目录。例如:--exclude-dir=/path/to/excluded
  • -l--files-with-matches):只显示包含匹配的文件名,而不显示匹配的具体行。
    • 例如:grep -l "pattern" file1.txt file2.txt
  • -L--files-without-match):只显示不包含匹配的文件名。
    • 例如:grep -L "pattern" file1.txt file2.txt
  • -Z--null):使用 NUL 字符作为文件名分隔符。NUL 字符是 ASCII 字符集中的控制字符,表示空字符或空值。它的 ASCII 值为 0(十进制)。在 Unix-like 系统中,NUL 字符通常用于表示字符串的结尾或作为文件名分隔符。grep 命令由此能够处理包含特殊字符或空格的文件名列表。Xargs命令也可以使用-0参数达到同样效果.
    • 例如:grep -lz "pattern" file1.txt file2.txt
      1
      2
      3
      4
      5
      6
      7
      8
      # 测试文件:
      echo "aaa" > file1
      echo "bbb" > file2
      echo "aaa" > file3

      grep "aaa" file* -lZ | xargs -0 rm

      # 执行后会删除file1和file3,grep输出用-Z选项来指定以0值字节作为终结符文件名(\0),xargs -0 读取输入并用0值字节终结符分隔文件名,然后删除匹配文件,-Z通常和-l结合使用。

控制匹配输出格式

  • -n--line-number):显示匹配行的行号。
    • 例如:grep -n "pattern" file.txt
  • -c--count):只显示匹配的行数。
    • 例如:grep -c "pattern" file.txt
  • -q--quiet):静默模式,不输出任何结果
    • 例如:grep -q "pattern" file.txt
  • -s--no-messages):静默模式,不显示错误信息
    • 例如:grep -s "pattern" file.txt
  • -o (--only-matching): 只显示匹配PATTERN 部分。

匹配 = 定位, 以下系数控制输出更多行, 譬如匹配一个ID, 输出它下面N行的数据.

  • -A num--after-context=num):显示匹配行之后的 num 行内容。
    • 例如:grep -A 3 "pattern" file.txt
  • -B num--before-context=num):显示匹配行之前的 num 行内容。
    • 例如:grep -B 2 "pattern" file.txt
  • -C num--context=num):显示匹配行之前和之后的 num 行内容。
    • 例如:grep -C 2 "pattern" file.txt
  • --group-separator=SEP: 将匹配的组(也即匹配的行以及要输出的上下文)用分隔符分开
  • -m num--max-count=num):设置匹配的最大行数。
    • 例如:grep -m 5 "pattern" file.txt

Sed命令:

1
sed [选项] [脚本命令] 文件名

参数解析

配置命令输出格式

  1. -n,--quiet, --silent:禁止自动打印模式空间的内容。默认情况下,sed会自动打印模式空间的内容到标准输出。使用-n参数后,只有通过sed的打印命令(例如p)才会输出内容。
  2. -i:直接在源文件中进行修改。默认情况下,sed会将修改后的结果输出到标准输出。使用-i参数后,sed会直接在源文件中进行修改,并将结果写入源文件。例如:sed -i 's/pattern/replacement/' file.txt

与grep命令中含义一致的参数:

  1. -e:允许在命令行上指定要执行的sed脚本。可以使用多个-e参数来指定多个命令。例如:sed -e 'command1' -e 'command2' file.txt。与Grep命令中含义一致.
  2. -f:从指定的文件中读取sed脚本。脚本文件中可以包含多个sed命令,每个命令占据一行。例如:sed -f script.sed file.txt。和Grep命令中含义一致.
  3. -r,-E,--regexp-extended:启用扩展的正则表达式语法。默认情况下,sed使用基本的正则表达式语法。使用-r参数后,可以使用更多的元字符和语法结构。-E与Grep命令中含义一致.
  4. -z:将输入文件视为以null字符分隔的记录。默认情况下,sed将输入文件视为以换行符分隔的记录。使用-z参数后,sed将输入文件视为以null字符(\0)分隔的记录。与Grep命令中含义一致.

处理方式控制

  1. -l N,--line-length=N: 在sed命令中,-l参数(或—line-length)用于指定输出行的最大长度。它限制了sed命令所产生的输出行的字符数量。当输出行的长度超过指定的最大长度时,sed命令将会对输出行进行截断,只保留指定长度的部分。这可以用来控制输出的格式,使得输出行在显示或处理上更易于处理。
  2. -s:在处理多个文件时,将每个文件视为独立的流。默认情况下,sed会将所有文件视为一个连续的流,并在所有文件上执行给定的命令。使用-s参数后,sed会将每个文件视为独立的流,并在每个文件上分别执行命令。file-wise形式执行命令.

不那么常用的参数(毕竟核心是命令):

  1. -b--binary:以二进制模式打开文件。默认情况下,sed将文件视为文本文件并以文本模式打开。使用-b参数后,sed将以二进制模式打开文件,可以用于处理二进制文件。
  2. -u--unbuffered:禁用输出缓冲。默认情况下,sed会在打印输出之前对其进行缓冲。使用-u参数后,禁用输出缓冲,使得输出立即可见。
  3. -y:执行逐字符替换。默认情况下,sed会按照给定的替换规则对文本进行模式匹配和替换。使用-y参数后,sed将执行逐字符的替换,将一个字符映射为另一个字符。
  4. -h--no-default-hold:禁用默认的模式保持空间。默认情况下,sed使用一个特殊的模式保持空间来存储处理过的行。使用-h参数后,禁用默认的模式保持空间,可以使用自定义的保持空间。
  5. -H--default-hold:启用默认的模式保持空间。如果在使用-h参数后想恢复默认的模式保持空间,可以使用-H参数。

command解析

sed命令语法格式为[addr]X[options], [addr]是可选参数, 控制X(单个字符,决定执行什么命令)处理的对象, 若[addr]为空则默认全部. 而[options]则是对于X而言的, 只有部分命令用得上.

[addr]可以是一个数值(sed '35d' input.txt), 正则表达式(sed '/^foo/q42' input.txt, 表示当该行找到时, 会以42状态码退出命令), 或是一个范围(sed '30,35d' input.txt).

执行多个命令有多种不同格式. 你可以使用;隔开, 命令会先后执行, 首先,/^foo/d这个命令会匹配以”foo”开头的行,并删除这些匹配到的行。这是一个针对行的操作。然后,s/hello/world/命令会在每一行中将第一个出现的”hello”替换为”world”。All characters following a,c,i commands are taken as the text to append/change/insert, 所以不能使用;分隔, 必须是-e参数或添加换行. r,R,w,W同理, 不过这次是文件名被破坏.

1
sed '/^foo/d ; s/hello/world/' input.txt > output.txt

你也可以使用-e参数指定不同命令:
1
sed -e '/^foo/d' -e 's/hello/world/' input.txt > output.txt

你甚至可以直接指定含有命令的文件:
1
2
3
echo '/^foo/d' > script.sed
echo 's/hello/world/' >> script.sed
sed -f script.sed input.txt > output.txt

括号 {} 用于分组多个命令,以便对一组命令进行相同的操作或逻辑控制。大括号 {} 内可以包含多个sed命令,每个命令之间使用分号 ; 分隔。当sed处理到大括号时,它会将大括号内的命令作为一个单独的组,并按照顺序逐个执行其中的命令。在匹配特定模式时执行一系列操作.
1
2
$ sed -e '/pattern/{s/foo/bar/; s/baz/qux/}' input.txt
#



以下单独解释下各个命令的作用.

常用命令

a\ (\n) text,a text: 在匹配处之后添加新行.
c\ (\n) text,c text: Replace (change) lines with text (alternative syntax).
d: Delete the pattern space; immediately start next cycle.
D: 用于删除模式空间中的第一个换行符及其之前的内容,并将剩余的内容重新加载到模式空间中,然后继续执行后续的sed命令。
s/regexp/replacement/[flags]: (substitute) Match the regular-expression against the content of the pattern space. If found, replace matched string with replacement.
i\ (a \n) text,i text: insert text before a line (alternative syntax).
e command: s/foo/echo bar/e命令将会将匹配到的”foo”替换为”echo bar”,然后执行这个替换后的内容作为Shell命令。该Shell命令的输出结果会取代原始匹配的文本。
需要注意的是,e命令只能在替换命令中使用,并且仅在替换命令的右侧才会生效。它不能用于其他sed命令或正则表达式的匹配部分。

1
$ sed 's/foo/echo bar/e' input.txt

模式空间与保持空间

模式空间是sed命令处理的主要工作区域,它会逐行地读取输入文本并进行处理。每次处理一行时,当前行的内容会存储在模式空间中。sed命令会对模式空间中的数据进行操作,例如匹配、替换、删除等操作。完成对当前行的处理后,模式空间会被清空,然后继续处理下一行。
保持空间是另一个临时存储区域,它可以用来存储额外的数据。保持空间在整个处理过程中可以持久存在,不会像模式空间那样在处理完一行后被清空。你可以使用sed命令的特定命令(如g、G、h、H等)来在模式空间和保持空间之间进行数据交换。这样可以在不同的行之间传递数据,或者将数据保存起来供后续处理使用。

g: 将保持空间中的内容复制到模式空间中。它会用保持空间的内容替换当前模式空间的内容。
G: 将保持空间中的内容追加到模式空间中的行后。在模式空间中的当前行和保持空间中的内容之间会添加一个换行符。
h: 将模式空间中的内容复制到保持空间中。它会用模式空间的内容替换当前保持空间的内容。
H: 将模式空间中的内容追加到保持空间中的行后。在保持空间中的当前行和模式空间中的内容之间会添加一个换行符。
x:交换两空间的内容;
z:(zap) This command empties the content of pattern space.
n: 当sed处理文件,遇到n命令时,它会将当前模式空间的内容输出,然后读取下一行,替换当前模式空间的内容。在下面的这个案例中, 每一次执行, 首先读取一行到模式空间并print, 随后n命令直接读取新的一行替换掉当前行, 后续命令会对该行进行处理(这里没有后续命令了), 同时由于该行已经被读取出来了, 第二次直接读取了第三行, 所以从结果上看类似与跳过了第二,四行.

1
2
3
4
5
6
7
8
9
10
11
sed -n '1,5 {p; n}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync

sed -n '1,5 p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync

N: 用于将下一行添加(而非替换)到模式空间中,并在两行之间插入一个换行符。这允许对多行文本进行操作。一旦多行文本位于模式空间中,可以使用其他sed命令对其进行处理,如正则表达式匹配、替换或删除等操作。
1
$ sed -n 'N; s/foo\nbar/baz/' input.txt

输出当前文本信息

p: Print the pattern space(单行或多行). 如果模式空间中有多行内容,p命令会将它们全部打印出来。
P: Print the pattern space, up to the first \. P命令用于将模式空间中的当前行的第一行部分复制到标准输出,并且只打印复制的部分。它不会打印整个匹配到的行。
l: 显示当前处理的文本行,并在行的末尾显示其非打印字符的编码。
F: 输出当前正在处理的文件的名称, 并附上一个换行符.
=: Print the current input line number (with a trailing newline).

标签跳转

b label:当sed解析到b命令时,它会立即跳转到指定的标签处,继续执行后续的命令。这意味着b命令可以用于跳过当前处理行中的后续命令,直接转到指定位置继续处理下一行。

1
2
3
4
5
6
7
8
9
$ sed '/pattern/ {
s/foo/bar/
b end
s/hello/world/
:end
}' input.txt
#如果某一行匹配了`/pattern/`模式,那么sed将执行该块内的命令。在
#这个块内,首先执行`s/foo/bar/`命令替换第一个出现的"foo"为"bar"。
#然后,`b end`命令会跳转到标签`:end`处,继续处理下一行,跳过了`s/hello/world/`命令。

t label: sed命令在执行过程中,会逐行处理输入文本。当遇到t命令时,它会检查最近执行的s(替换)命令是否成功(即是否有发生替换)。如果有替换发生,t命令将会将控制转移到指定的标签处继续执行后续命令。
1
2
3
4
$ sed 's/foo/bar/ ; t label ; s/123/456/' input.txt
#`s/foo/bar/`命令会尝试将每一行中的"foo"替换为"bar"。
#如果发生了替换,`t label`命令将跳转到标签`label`处继续执行后续命令,即`s/123/456/`命令。
#如果没有发生替换,`t label`命令不会执行跳转,直接执行下一个命令。

T label: 含义与t相反, 当不成功时进行跳转.
#: A comment, until the next newline.
: label: Specify the location of label for branch commands (b, t, T).

其他

q[exit-code]: (quit) Exit sed without processing any more commands or input.
Q[exit-code]:(quit) This command is the same as q, but will not print the contents of pattern space. Like q, it provides the ability to return an exit code to the caller.
w filename:用于将匹配到的行写入指定的文件。语法为:w filename,其中filename是要写入的文件名。例如,/pattern/w output.txt会将匹配到模式pattern的行写入到output.txt文件中。如果output.txt文件已存在,行将被追加到文件末尾;如果文件不存在,将创建新文件。
W filename:与w命令类似,但它只写入匹配到模式的行中的第一行,并且在写入后删除该行。语法为:W filename,其中filename是要写入的文件名。例如,/pattern/W output.txt会将匹配到模式pattern的行中的第一行写入到output.txt文件中,并在写入后将该行从模式空间中删除。
r filename:Reads file filename.
R filename:Queue a line of filename to be read and inserted into the output stream at the end of the current cycle, or when the next input line is read.


如何选择行?

  1. 直接通过行号:
    1. number: 选择对应行
    2. $: 选择最后一行
    3. first~step: 从first开始, 以step为步长选择行.
  2. 通过正则表达式: 默认使用BRE(Grep也是), 除非指定-E,-r参数.
    1. /regexp/: 注意当使用//即空的正则时, 会使用上一个正则, 不论是;,-e,-f方法指定的.
    2. \%regexp%: %可以是任何其他单字符. 主要用在需要匹配路径的情况, 毕竟一个个转义也太麻烦了.
    3. /regexp/I,\%regexp%I: I修饰符的作用主要是令匹配大小写不敏感. 注意i是插入命令, 并非大小写敏感开关!
    4. /regexp/M, \%regexp%M: M意为multiple, 开启多行模式, ^$只会匹配空行, 而非buffer的起点和终点(\` 和\‘, 注意一个是行内代码符号`, 一个是单引号).
  3. 通过范围:
    1. num1,num2: 匹配 [num1, num2]行, 包含num1,2. 注意若num2\<num1, 则仅取一行.
    2. 0,/regexp/: 1,/regexp/会导致第一行中regex不被匹配到.
    3. addr1,+N: 匹配addr1后面N行.
    4. addr1,~N: 从匹配到addr1开始, 一直到下一个N的整数倍行.

一些例子

可以点击这里查看sed官方提供的例子, 很详细, 你可以学习到如何写一个sed脚本.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/sed -f

# Put 80 spaces in the buffer
1 {
x
s/^$/ /
s/^.*$/&&&&&&&&/
x
}

# delete leading and trailing spaces
y/TAB/ /
s/^ *//
s/ *$//

# add a newline and 80 spaces to end of line
G

# keep first 81 chars (80 + a newline)
s/^\(.\{81\}\).*$/\1/

# \2 matches half of the spaces, which are moved to the beginning
s/^\(.*\)\n\(.*\)\2/\2\1/

Awk命令

前面已经介绍了两种工具,其中:grep 主要用于在文件中搜索匹配的行,适用于简单的文本搜索和过滤; sed 主要用于对文本进行转换、替换和删除等操作,适用于对文本进行批量处理。而 awk 主要用于处理结构化文本数据,通过分割字段和处理行来提取和转换数据,适用于处理复杂的文本处理任务。

参数解析