SED命令

112 阅读9分钟

sed的背景

sed(Stream Editor)是一种流式文本编辑器,用于在命令行环境下对文本进行转换和处理。它是根据Unix操作系统中的ed编辑器发展而来的,最早由Lee E. McMahon于1973年开发。sed在Unix和类Unix系统中广泛使用,并成为标准工具集中的重要组成部分。

sed的设计理念是基于一次处理一行文本的原则。它从输入流中逐行读取文本数据,对每一行应用编辑操作,并将结果输出到标准输出流。sed以其简洁、高效和强大的文本处理能力而受到广泛赞誉。

sed的功能

sed具有丰富的功能和灵活的操作方式,它可以通过编辑命令来实现各种复杂的文本操作(这些命令可以是单个命令或多个命令的组合;sed支持正则表达式,可以使用正则表达式来匹配和处理文本数据)。它在命令行环境下广泛应用于文本处理、数据转换、文件批量处理等场景。

流式编辑

sed 以行为单位处理文本数据,从输入流中逐行读取文本,对每一行应用编辑操作,并将结果输出到标准输出流。如:

echo "Hello, world!" | sed 's/world/John/'

输出:

Hello, John!
基于编辑命令

sed 使用编辑命令来指定对文本的操作。编辑命令可以是单个命令或多个命令的组合,通过分号 ; 分隔。每个命令都指定了要执行的操作,如打印行、替换文本、删除行等。

echo "Hello, world!" | sed 's/world/John/;s/Hello/Hi/'

输出:

Hi, John!
正则表达式

sed 支持正则表达式,可以使用正则表达式来匹配和处理文本数据。正则表达式可以用于匹配模式、替换文本、地址定位等。

echo "apple banana" | sed 's/a.*e/orange/'

正则表达式a.*e匹配a后面跟着任意数量的字符,直到遇到最后一个e。因此,它将apple替换为orange。

输出:

orange banana
替换和删除

sed 可以替换匹配到的文本或删除指定的行。

echo "apple apple apple" | sed 's/apple/orange/2'

输出:

apple orange apple
地址定位

sed 允许使用地址定位来选择要操作的行的范围。地址可以是行号、正则表达式匹配、行范围等。

echo -e "Line 1\nLine 2\nLine 3" | sed '/2/,/3/s/Line/Number/'

使用地址定位来选择要操作的行的范围,即从包含"2"的行到包含"3"的行之间。在这个范围内,执行替换操作's/Line/Number/',将每一行中的第一个匹配的"Line"替换为"Number"。

输出:

Line 1
Number 2
Number 3
批量处理

sed 可以处理大量的文本数据,适用于批量处理文件、文本转换、数据清洗等任务。

sed 's/apple/orange/' file.txt > output.txt

将文件 file.txt 中的所有 "apple" 替换为 "orange",并将结果保存到 output.txt 文件中。

原地编辑

sed 支持在原始文件上进行直接编辑,即原地编辑。通过 -i 选项,可以将编辑结果直接保存到原始文件中,而无需将结果输出到标准输出流。

sed -i 's/apple/orange/' file.txt

将文件 file.txt 中的所有 "apple" 替换为 "orange",并直接在原始文件上进行编辑。

脚本和命令行

sed 可以通过脚本文件或命令行进行使用。通过将编辑命令放入脚本文件中,可以在需要时调用脚本文件进行文本处理。 创建一个名为 script.sed 的脚本文件,内容如下:

s/apple/orange/

运行如下命令:

sed -f script.sed file.txt

将会执行脚本文件 script.sed 中的编辑命令,将文件 file.txt 中的所有 "apple" 替换为 "orange"。

sed的基本正则表达式

sed(Stream Editor)的基本正则表达式(BRE)是一种文本模式匹配和替换工具中常用的语法。基本正则表达式是提供了一组基本的模式匹配规则,用于在Sed中进行基本的文本模式匹配和替换操作。它可以用于删除、替换、插入和打印文本等各种文本处理任务。

基本正则表达式中的主要特性包括:

字符匹配
  • 匹配普通字符:表达式中的普通字符与目标文本中的相应字符匹配。表达式:sed 's/cat/dog/',描述:将目标文本中的 "cat" 替换为 "dog"。
  • .(点号):匹配任意一个字符(除了换行符)。表达式:sed 's/c.t/dog/',描述:将目标文本中的 "cat" 替换为 "dog"。
  • \(反斜杠):用于转义特殊字符,使其失去特殊含义。表达式:sed 's/c\.t/dog/',描述:将目标文本中的 "c.t" 替换为 "dog"。
字符类
  • [](方括号):定义一个字符类,匹配括号内的任何一个字符。表达式:sed 's/[aeiou]/X/',描述:将目标文本中的任何一个元音字母替换为 "X"。
  • [^](反向字符类):定义一个反向字符类,匹配不在括号内的任何一个字符。表达式:sed 's/[^0-9]/X/',描述:将目标文本中的任何一个非数字字符替换为 "X"。
重复匹配
  • *(星号):匹配前面的元素零次或多次。表达式:sed 's/ab*c/dog/',描述:将目标文本中的 "ac"、"abc"、"abbc" 等替换为 "dog"。
  • \+(加号):匹配前面的元素一次或多次。表达式:sed 's/ab\+c/dog/',描述:将目标文本中的 "abc"、"abbc" 等替换为 "dog",不匹配 "ac"。
  • \?(问号):匹配前面的元素零次或一次。表达式:sed 's/ab\?c/dog/',描述:将目标文本中的 "ac"、"abc" 替换为 "dog",不匹配 "abbc"。 - \{n\}:匹配前面的元素恰好 n 次。表达式:sed 's/a\{3\}/dog/',描述:将目标文本中连续的三个 "a" 替换为 "dog"。
  • \{n,m\}:匹配前面的元素至少 n 次,最多 m 次。表达式:sed 's/a\{2,4\}/dog/',描述:将目标文本中连续的两个到四个 "a" 替换为 "dog"。
锚定
  • ^(脱字符):匹配行的开头。表达式:sed '/^abc/d',描述:删除以 "abc" 开头的行。
  • $(美元符号):匹配行的结尾。表达式:sed '/xyz$/d',描述:删除以 "xyz" 结尾的行。
  • \<\>\<表示单词的开头,\> 表示单词的结尾。表达式:sed 's/\<apple\>/banana/g' file.txt,描述:将匹配文件 "file.txt" 中的单词 "apple为 "banana"。
分组和引用
  • \(\):用于创建一个组,将其中的表达式作为一个单元进行匹配。表达式:sed 's/\(abc\)\(def\)/\2\1/',描述:将匹配到的 "abc" 和 "def" 进行交换,并进行替换操作。
  • \n:在替换操作中引用之前创建的组。\n 中的 n 是数字,表示引用第n个组的内容。

sed的扩展正则表达式

扩展正则表达式(Extended Regular Expression,ERE)是正则表达式的一种扩展形式,提供了比基本正则表达式(Basic Regular Expression,BRE)更多的功能和元字符。ERE广泛用于各种文本处理工具和编程语言中,如grep、sed、awk以及Perl等。

扩展正则表达式与基本正则表达式的主要区别在于功能特点和语法元素。

功能特点区别

ERE支持更多的元字符和功能

  • +:匹配前一个元素的一个或多个实例。表达式:sed -E 's/foo+bar/baz/' file.txt,描述:将匹配到的"foobar"替换为"baz"。
  • ?:匹配前一个元素的零个或一个实例。表达式:sed -E 's/foo(bar)?/baz/' file.txt,描述:将匹配到的"foobar"替换为"baz"。
  • |:逻辑或操作,匹配多个模式中的任意一个。表达式:sed -E -e '/foo|bar/d' file.txt,描述:删除包含"foo"或"bar"的行。
  • ():分组和引用,用于提取匹配的子字符串。表达式:sed -E 's/(foo)(bar)/\2\1/' file.txt,描述:将"foobar"替换为"barfoo"。
  • {}:限定符,指定前一个元素的匹配次数范围。表达式:sed -E 's/foo{2,4}/bar/' file.txt,描述:将连续2到4个"foo"替换为"bar"。

ERE支持更多的转义字符

  • \b:匹配单词边界。表达式:sed 's/\btest\b/replacement/' file.txt,描述:将独立的单词"test"替换为"replacement"。
  • \s:匹配空白字符。表达式:sed 's/\s//g' file.txt,描述:将空格字符删除。
  • \w:匹配字母数字字符。表达式:sed 's/\w/replacement/g' file.txt,描述:将字母或数字字符替换为"replacement"。
  • \d:匹配数字字符。表达式:sed 's/[[:digit:]]/replacement/g' file.txt,描述:将数字字符替换为"replacement"。

ERE支持更多的字符组表达式

在基本正则表达式(BRE)中,相应的字符类表达法是没有冒号的。

  • [[:alpha:]]:在基本正则表达式中可以表示为 [a-zA-Z],用于匹配字母字符(包括大小写字母)。表达式:sed 's/[[:alpha:]]/X/g' file.txt,描述:将文本中的字母字符替换为 X。
  • [[:digit:]]:在基本正则表达式中可以表示为 [0-9],用于匹配数字字符。表达式:sed 'sed 's/[[:digit:]]/0/g' file.txt,描述:将文本中的数字字符替换为 0。
  • [[:alnum:]]:在基本正则表达式中可以表示为 [a-zA-Z0-9],用于匹配字母和数字字符。表达式:sed 'sed 's/[[:alnum:]]/#/g' file.txt,描述:将文本中的字母和数字字符替换为 #。
  • [[:space:]]:在基本正则表达式中可以表示为空白字符的集合,包括空格、制表符、换行符等。可以使用 [\t\n\r\f\v ] 来表示,用于匹配空白字符。表达式:sed 's/[[:space:]]/,/g' file.txt,描述:将文本中的空白字符替换为逗号。
  • [[:word:]]:在基本正则表达式中没有直接等效的字符类,但可以使用[[:alnum:]]和下划线来近似表示单词字符,即 [a-zA-Z0-9_],用于匹配字母数字字符。表达式:sed 's/[[:word:]]/*/g' file.txt,描述:将文本中的单词字符替换为 *。
语法元素区别
  • 在ERE中,元字符+?|()不需要进行转义。
  • 在ERE中,元字符{}中的逗号,不需要转义,而在BRE中,需要使用\{\}进行转义。
sed命令使用区别
  • 在sed命令中,默认使用BRE,如果要使用ERE,需要使用-E选项进行指定。
  • 使用BRE时,元字符和语法元素需要使用反斜杠进行转义;使用ERE时,不需要对元字符和语法元素进行转义,可以直接使用其特定功能。