`

sed替换

阅读更多
让我们看一下 sed 最有用的命令之一,替换命令。使用该命令,可以将特定字符串或匹配的规则表达式用另一个字符串替换。下面是该命令最基本用法的示例:



$ sed -e 's/foo/bar/' myfile.txt

上面的命令将 myfile.txt 中每行第一次出现的 'foo'(如果有的话)用字符串 'bar' 替换,然后将该文件内容输出到标准输出。请注意,我说的是每行第一次出现,尽管这通常不是您想要的。在进行字符串替换时,通常想执行全局替换。也就是说,要替换每行中的所有出现,如下所示:



$ sed -e 's/foo/bar/g' myfile.txt

在最后一个斜杠之后附加的 'g' 选项告诉 sed 执行全局替换。

关于 's///' 替换命令,还有其它几件要了解的事。首先,它是一个命令,并且只是一个命令,在所有上例中都没有指定地址。这意味着,'s///' 还可以与地址一起使用来控制要将命令应用到哪些行,如下所示:



$ sed -e '1,10s/enchantment/entrapment/g' myfile2.txt

上例将导致用短语 'entrapment' 替换所有出现的短语 'enchantment',但是只在第一到第十行(包括这两行)上这样做。



$ sed -e '/^$/,/^END/s/hills/mountains/g' myfile3.txt

该例将用 'mountains' 替换 'hills',但是,只从空行开始,到以三个字符 'END' 开始的行结束(包括这两行)的文本块上这样做。

关于 's///' 命令的另一个妙处是 '/' 分隔符有许多替换选项。如果正在执行字符串替换,并且规则表达式或替换字符串中有许多斜杠,则可以通过在 's' 之后指定一个不同的字符来更改分隔符。例如,下例将把所有出现的 /usr/local 替换成 /usr:



$ sed -e 's:/usr/local:/usr:g' mylist.txt

在该例中,使用冒号作为分隔符。如果不指定分隔符,则变成了如下:



$ sed -e 's/usr/local/usrg' mylist.txt

这样就不能执行了
如果需要在规则表达式中指定分隔符字符,可以在它前面加入反斜杠。


规则表达式混乱
目前为止,我们只执行了简单的字符串替换。虽然这很方便,但是我们还可以匹配规则表达式。例如,以下 sed 命令将匹配从 '<' 开始、到 '>' 结束、并且在其中包含任意数量字符的短语。下例将删除该短语(用空字符串替换):



$ sed -e 's/<.*>//g' myfile.html

这是要从文件除去 HTML 标记的第一个很好的 sed 脚本尝试,但是由于规则表达式的特有规则,它不会很好地工作。原因何在?当 sed 试图在行中匹配规则表达式时,它要在行中查找最长的匹配。在我的前一篇 sed 文章中,这不成问题,因为我们使用的是 'd' 和 'p' 命令,这些命令总要删除或打印整行。但是,在使用 's///' 命令时,确实有很大不同,因为规则表达式匹配的整个部分将被目标字符串替换,或者,在本例中,被删除。这意味着,上例将把下行:


<b>This</b> is what <b>I</b> meant.

变成:
meant.
我们要的不是这个,而是:
This is what I meant.

幸运的是,有一种简便方法来纠正该问题。我们不输入“'<' 字符后面跟有一些字符并以 '>' 字符结束”的规则表达式,
而只需输入一个“'<' 字符,后面跟有任意数量非 '>' 字符,并以 '>' 字符结束”的规则表达式。这将与最短、而不是最长的可能性匹配。新命令如下:



$ sed -e 's/<[^>]*>//g' myfile.html

在上例中,'[^>]' 指定“非 '>'”字符,其后的 '*' 完成该表达式以表示“零或多个非 '>' 字符”。对几个 html 文件测试该命令,将它们管道输出 "more",然后仔细查看其结果。


更多字符匹配
'[ ]' 规则表达式语法还有一些附加选项。要指定字符范围,只要字符不在第一个或最后一个位置,就可以使用 '-',如下所示:

QUOTE:
'[a-x]*'
这将匹配零或多个全部为 'a'、'b'、'c'...'v'、'w'、'x' 的字符。另外,可以使用 '[]' 字符类来匹配空格。以下是可用字符类的相当完整的列表:

字符类 描述
[] 字母数字 [a-z A-Z 0-9]
[] 字母 [a-z A-Z]
[] 空格或制表键
[] 任何控制字符
[] 数字 [0-9]
[] 任何可视字符(无空格)
[] 小写 [a-z]
[] 非控制字符
[] 标点字符
[] 空格
[] 大写 [A-Z]
[] 十六进制数字 [0-9 a-f A-F]

尽可能使用字符类是很有利的,因为它们可以更好地适应非英语 locale(包括某些必需的重音字符等等).


高级替换功能
我们已经看到如何执行简单甚至有些复杂的直接替换,但是 sed 还可以做更多的事。实际上可以引用匹配规则表达式的部分或全部,并使用这些部分来构造替换字符串。作为示例,假设您正在回复一条消息。下例将在每一行前面加上短语 "ralph said: ":



$ sed -e 's/.*/ralph said: &/' origmsg.txt

输出如下:


ralph said: Hiya Jim, ralph said: ralph said:
I sure like this sed stuff! ralph said:

该例的替换字符串中使用了 '&' 字符,该字符告诉 sed 插入整个匹配的规则表达式。因此,可以将与 '.*' 匹配的任何内容(行中的零或多个字符的最大组或整行)插入到替换字符串中的任何位置,甚至多次插入。这非常好,但 sed 甚至更强大。


那些极好的带反斜杠的圆括号
's///' 命令甚至比 '&' 更好,它允许我们在规则表达式中定义区域,然后可以在替换字符串中引用这些特定区域。作为示例,假设有一个包含以下文本的文件:


foo bar oni eeny meeny miny larry curly moe jimmy the weasel

现在假设要编写一个 sed 脚本,该脚本将把 "eeny meeny miny" 替换成 "Victor eeny-meeny Von miny" 等等。要这样做,首先要编写一个由空格分隔并与三个字符串匹配的规则表达式。


'.* .* .*'

现在,将在其中每个感兴趣的区域两边插入带反斜杠的圆括号来定义区域:


'\(.*\) \(.*\) \(.*\)'

除了要定义三个可在替换字符串中引用的逻辑区域以外,该规则表达式的工作原理将与第一个规则表达式相同。下面是最终脚本:



$ sed -e 's/\(.*\) \(.*\) \(.*\)/Victor \1-\2 Von \3/' myfile.txt

如您所见,通过输入 '\x'(其中,x 是从 1 开始的区域号)来引用每个由圆括号定界的区域。输入如下:


Victor foo-bar Von oni Victor eeny-meeny Von miny Victor larry-curly Von moe Victor jimmy-the Von weasel

随着对 sed 越来越熟悉,您可以花最小力气来进行相当强大的文本处理。您可能想如何使用熟悉的脚本语言来处理这种问题 -- 能用一行代码轻易实现这样的解决方案吗?


组合使用
在开始创建更复杂的 sed 脚本时,需要有输入多个命令的能力。有几种方法这样做。首先,可以在命令之间使用分号。例如,以下命令系列使用 '=' 命令和 'p' 命令,'=' 命令告诉 sed 打印行号,'p' 命令明确告诉 sed 打印该行(因为处于 '-n' 模式)。



$ sed -n -e '=;p' myfile.txt

无论什么时候指定了两个或更多命令,都按顺序将每个命令应用到文件的每一行。在上例中,首先将 '=' 命令应用到第 1 行,然后应用 'p' 命令。接着,sed 继续处理第 2 行,并重复该过程。虽然分号很方便,但是在某些场合下,它不能正常工作。另一种替换方法是使用两个 -e 选项来指定两个不同的命令:



$ sed -n -e '=' -e 'p' myfile.txt

然而,在使用更为复杂的附加和插入命令时,甚至多个 '-e' 选项也不能帮我们的忙。对于复杂的多行脚本,最好的方法是将命令放入一个单独的文件中。然后,用 -f 选项引用该脚本文件:



$ sed -n -f mycommands.sed myfile.txt

这种方法虽然可能不太方便,但总是管用。


一个地址的多个命令
有时,可能要指定应用到一个地址的多个命令。这在执行许多 's///' 以变换源文件中的字和语法时特别方便。要对一个地址执行多个命令,可在文件中输入 sed 命令,然后使用 '{ }' 字符将这些命令分组,如下所示:


1,20{         s/[Ll]inux/GNU\/Linux/g         s/samba/Samba/g         s/posix/POSIX/g }

上例将把三个替换命令应用到第 1 行到第 20 行(包括这两行)。还可以使用规则表达式地址或者二者的组合:


1,/^END/{         s/[Ll]inux/GNU\/Linux/g         s/samba/Samba/g         s/posix/POSIX/g         p }

该例将把 '{ }' 之间的所有命令应用到从第 1 行开始,到以字母 "END" 开始的行结束(如果在源文件中没发现 "END",则到文件结束)的所有行。


附加、插入和更改行
既然在单独的文件中编写 sed 脚本,我们可以利用附加、插入和更改行命令。这些命令将在当前行之后插入一行,在当前行之前插入一行,或者替换模式空间中的当前行。它们也可以用来将多行插入到输出。插入行命令用法如下:


i\ This line will be inserted before each line

如果不为该命令指定地址,那么它将应用到每一行,并产生如下的输出:


This line will be inserted before each line line 1 here
This line will be inserted before each line line 2 here
This line will be inserted before each line line 3 here
This line will be inserted before each line line 4 here

如果要在当前行之前插入多行,可以通过在前一行之后附加一个反斜杠来添加附加行,如下所示:


i\ insert this line\ and this one\ and this one\ and, uh, this one too.

附加命令的用法与之类似,但是它将把一行或多行插入到模式空间中的当前行之后。其用法如下:


a\ insert this line after each line.  Thanks!

另一方面,“更改行”命令将实际替换模式空间中的当前行,其用法如下:


c\ You're history, original line! Muhahaha!

因为附加、插入和更改行命令需要在多行输入,所以将把它们输入到一个文本 sed 脚本中,然后通过使用 '-f' 选项告诉 sed 执行它们。使用其它方法将命令传递给 sed 会出现问题。

分享到:
评论
1 楼 guji528 2012-06-18  
感受到sed的强大

相关推荐

    Python 实现简单的shell sed替换功能(实例讲解)

    总结,通过Python实现的这个简单shell sed替换功能,我们可以看到Python编程语言在文本处理方面的能力,它允许我们在不依赖外部命令行工具的情况下完成文件内容的修改。这种方法对于跨平台的自动化脚本或者需要更多...

    sed and awk 101 hacks

    第三章介绍了正则表达式的基础(RegularExpressionFundamentals)和一些额外的正则表达式(AdditionalRegularExpressions),以及如何在sed替换中使用它们(SedSubstitutionUsingRegularExpression)。 第四章讨论...

    Sed AWK编程指南

    sed 's/old/new/\L/g' file.txt # 将替换后的字符串全部转换为小写 ``` #### 四、正则表达式 ##### 20. 正则表达式基础 正则表达式是用于匹配字符串的强大工具,`sed` 支持多种正则表达式语法。 示例: ``` sed ...

    sed and awk 101 hacks.pdf

    - **sed替换命令语法**:替换命令是最常用的sed功能之一,它允许用户在文件中查找和替换字符串。 - **全局标志g**:标志g(global)表示对找到的每一处匹配都执行替换操作。 - **数字标志和打印标志p**:数字标志...

    Sed & Awk 101 Hacks

    #### 第二章:Sed替换命令 **6. Sed替换命令语法** Sed提供了一个强大的替换命令`s`,用于替换文本中的字符串。 示例: ``` sed 's/old/new/g' file ``` 这将在文件的所有行中将所有的`old`替换为`new`。 **7. ...

    sed与awk(第二版)

    例如,用sed替换文本中的特定字符串: ```bash sed 's/old/new/g' filename ``` 这会将`filename`中所有出现的"old"替换为"new"。`s`是替换命令,`g`是全局替换标志,表示替换每行中所有匹配的实例。 awk(AWK ...

    sed&awk101 Hacks

    sed替换命令是sed功能中比较复杂的部分,涉及全局标志(g)、数字标志、打印标志(p)、写标志(w)、忽略大小写标志(i)、执行命令标志(e)等。sed的替换命令也支持使用正则表达式。在执行sed部分,手册详细介绍...

    linux脚本编程中的sed详解

    - 示例:`cat file | sed 's/abc/def/g' | grep 'def'` 首先使用sed替换所有“abc”为“def”,然后使用grep筛选出包含“def”的行。 ### 总结 sed是一款功能强大的文本处理工具,在Linux脚本编程中有着广泛的...

    Linux_sed_批量替换字符串方法

    ### Linux sed 批量替换字符串方法详解 #### 一、sed简介 `sed`(stream editor)是一款功能强大的文本处理工具,在Linux系统中被广泛应用于批量处理文本文件,特别是进行字符串查找、替换等操作。本文将详细介绍...

    Linuxsed批量替换字符串方法.pdf

    sed的替换功能基本语法是`sed 's/原字符串/新字符串/g' 文件名`,其中`'s'`表示替换操作,`'g'`表示全局替换,即在一行中出现的所有匹配项都会被替换。 例如,将文件中的所有“zhangsan”替换为“lisi”: ```bash ...

    Sed and Awk 101 Hacks

    接下来,Sed的替换命令将作为重点,包括替换命令的语法、使用全局标志、数字标志、打印标志、写标志、忽略大小写标志、执行命令标志等,以及如何在sed替换中使用正则表达式。 为了提升处理效率,Sed允许在单一...

    Linux使用sed命令替换字符串教程

    在Linux系统中,`sed`(流编辑器,Stream Editor)是一个强大的文本处理工具,用于在输入流中进行模式匹配和替换操作。本文将详细介绍如何使用`sed`命令来替换字符串,并探讨其相关的选项和用法。 ### 基本替换语法...

    Sed与awk第三版(高清版)

    例如,用sed替换配置文件中的敏感信息,用awk处理和分析系统日志,查找性能瓶颈。 9. **学习资源**:《sed与awk》一书提供了深入浅出的讲解和实例,是学习这两个工具的优秀教材。书中涵盖了基础概念、高级技巧以及...

    LINUX_sed_使用

    例如,用sed替换所有"hello"为"world",命令如下: ```bash sed 's/hello/world/g' input.txt &gt; output.txt ``` 这会将`input.txt`中的"hello"替换为"world",并将结果输出到`output.txt`。 ### 7. 脚本 Sed脚本...

    shell脚本修改json中某个字段的值

    # 使用sed替换旧值为新值 sed "s/\"\($field_to_change\)\":\"[^\"]*\"/\"\1\":\"$new_value\"/" ``` 这个脚本首先通过awk命令定位到包含指定字段的那一行,然后使用getline获取下一行(通常是包含字段值的那一行...

    sed and awk 101 hacks.pdf (中文版带书签)

    **Sed替换命令**是其核心功能之一,可以使用正则表达式进行复杂的替换操作。一些常用的替换标志包括: - **全局替换(g)**:`g`标志使得替换全局生效,替换所有匹配项,而不仅仅是第一个。 - **数字标志**:如`1,2,3...

    批量替换程序的文件注释头

    # 使用sed替换文件中的旧注释头 sed -i '' '0,/^#!/s//'"$NEW_HEADER"'/' "$file" fi done ``` 这个脚本会遍历指定目录,找到每个文件,然后用`sed`命令将文件的开头从旧注释头替换为新的注释头。 接下来,我们...

    sedsed工具

    2. **替换操作**:`sedsed 's/old/new/g' file.txt` 将`file.txt`中所有"old"替换为"new"。 3. **条件删除与替换结合**:`sedsed -d '/pattern/; s/another_pattern/replacement/g' file.txt` 删除匹配`pattern`的行...

    sed-4.2.1.rar包括sed-4.2.1-setup.exe、sed-4.2.1-dep.zip、sed-4.2.1-bin.zip

    1. **文本替换**:`sed`最基础的功能就是替换文本,例如,用新的字符串替换旧的字符串,或者根据正则表达式进行更复杂的替换。 2. **行过滤**:`sed`可以按条件打印或删除特定行,这对于处理日志文件或数据分析非常...

Global site tag (gtag.js) - Google Analytics