如何使用 Linux sed 命令自动进行文件编辑
sed 编辑器
![](/data/attachment/album/202208/17/120535by5jfu5dovfesd56.jpg)



> 
> 以下是从 Linux 命令行自动编辑文件的一些提示和技巧。
> 
> 
> 


当我使用 Linux 命令行时，无论是在台式机上编写新程序还是在 Web 服务器上管理网站，我经常需要处理文本文件。Linux 提供了强大的工具，我可以利用这些工具来完成我的工作。我经常使用 `sed`，一个可以根据模式修改文本的编辑器。


`sed` 代表 <ruby> 流编辑器 <rt>  Stream EDitor </rt></ruby>，它编辑文件中的文本并打印结果。使用 `sed` 的一种方法是识别一个字符串在文件中的几次出现，并将它们替换为不同的字符串。使用 `sed` 来处理文本文件的方式似乎是无穷无尽的，但我想分享一些使用 `sed` 来帮助我管理文件的方法。


### 在 Linux 上搜索和替换文件中的文本


要使用 `sed`，你需要使用一个*正则表达式*。正则表达式是定义模式的一组特殊字符。我最常使用 `sed` 的例子是替换文件中的文本。替换文本的语法如下：`s/originaltext/newtext`。`s` 告诉 `sed` 执行文本替换或交换出现的文本。在斜线之间提供原始文本和新文本。


此语法将仅替换每行中第一次出现的 `originaltext`。要替换每个匹配项，即使在一行中原始文本出现了不止一次，要将 `g` 追加到表达式的末尾。例如：`s/originaltext/newtext/g`。


要在 `sed` 中使用此表达式，请使用 `-e` 选项指定此正则表达式：



```
$ sed -e 's/originaltext/newtext/g'

```

例如，假设我有一个名为 `game` 程序的 Makefile 文件，该程序模拟了康威的《生命游戏》：



```
.PHONY: all run clean

all: game

game: game.o
        $(CC) $(CFLAGS) -o game game.o $(LDFLAGS)

run: game
        ./game

clean:
        $(RM) *~
        $(RM) *.o
        $(RM) game

```

`game` 这个名字并不是很有描述性，所以我想会把它改名为 `life`。将 `game.c` 源文件重命名为 `life.c` 非常简单，但现在我需要修改 Makefile 以使用新名称。我可以使用 `sed` 来将所有的 `game` 更改为 `life`：



```
$ sed -e 's/game/life/g' Makefile
.PHONY: all run clean

all: life

life: life.o
        $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)

run: life
        ./life

clean:
        $(RM) *~
        $(RM) *.o
        $(RM) life

```

`sed` 会将输出打印到屏幕上，这是检查文本替换是否符合你要求的好方法。要对 Makefile 进行这些更改，首先，备份文件，然后运行 `sed` 并将输出保存到原始文件名：



```
$ cp Makefile Makefile.old
$ sed -e 's/game/life/g' Makefile.old > Makefile

```

如果你确信你的更改正是你想要的，请使用 `-i` 或 `--in-place` 选项来编辑文件。但是，我建议添加一个备份文件后缀，如 `--in-place=.old`，用来备份原始文件，以备日后需要恢复时使用。它看起来像这样：



```
$ sed --in-place=.old -e 's/game/life/g' Makefile
$ ls Makefile*
Makefile  Makefile.old

```

### 在 Linux 上使用 sed 引用文件


你可以使用正则表达式的其它功能来匹配特定的文本实例。例如，你可能需要替换出现在行首的文本。使用 `sed`，你可以用上尖号 `^` 来匹配行的开头。


我使用“行首”来替换文本的一种方式是当我需要在电子邮件中引用一个文件时。假设我想在电子邮件中共享我的 Makefile，但我不想将其作为文件附件包含在内。相反，我更喜欢在电子邮件正文中“引用”文件，在每行之前使用 `>`。我可以使用以下 `sed` 命令将编辑后的版本打印到我的终端，并将其复制粘贴到新的电子邮件中：



```
$ sed -e 's/^/>/' Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
>       $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
>       ./life
>
>clean:
>       $(RM) *~
>       $(RM) *.o
>       $(RM) life

```

`s/^/>/` 正则表达式匹配每行的开头（`^`），并在那里放置一个 `>`。实际上，这相当于每行都以 `>` 符号开始。


制表符可能无法在电子邮件中正确显示，但我可以通过添加另一个正则表达式将 Makefile 中的所有制表符替换为几个空格：



```
$ sed -e 's/^/>/' -e 's/\t/  /g' Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
>  $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
>  ./life
>
>clean:
>  $(RM) *~
>  $(RM) *.o
>  $(RM) life

```

`\t` 表示文字制表符，因此 `s/\t/ /g` 告诉 `sed` 用输出中的两个空格替换输入中的所有制表符。


如果你需要对文件进行大量编辑，你可以将 `-e` 命令保存在文件中，并使用 `-f` 选项来告诉 `sed` 将该文件用作“脚本”。如果你需要经常进行相同的编辑，这种方法特别有用。我已经准备了 `quotemail.sed` 的脚本文件来在我的电子邮件中引用 Makefile：



```
$ cat quotemail.sed
s/^/>/
s/\t/  /g
$ sed -f quotemail.sed Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
>  $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
>  ./life
>
>clean:
>  $(RM) *~
>  $(RM) *.o
>  $(RM) life

```

### 学习在 Linux 上使用 sed


`sed` 是一个很好的工具，可以保存在你的 Linux 命令行工具包中。浏览 `sed` 手册页并了解有关如何使用它的更多信息。在命令行中键入 `man sed` 以获取有关不同命令行选项的完整文档，以及如何使用 `sed` 处理文本文件。




---


via: <https://opensource.com/article/22/8/automate-file-edits-sed-linux>


作者：[Jim Hall](https://opensource.com/users/jim-hall) 选题：[lkxed](https://github.com/lkxed) 译者：[perfiffer](https://github.com/perfiffer) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
When I use the Linux command line, whether I'm writing a new program on my desktop computer or managing a website on my web server, I often need to process text files. Linux provides powerful tools that I leverage to get my work done. I frequently use `sed`

, an editor that can modify text according to a pattern.

`sed`

stands for *stream editor*, and it edits text in a file and prints the results. One way to use `sed`

is to identify several occurrences of one string in a file and replace them with a different string. You can use `sed`

to process text files to a seemingly endless degree, but I'd like to share a few ways I use `sed`

to help me manage files.

## Search and replace text in a file on Linux

To use `sed`

, you need to use a *regular expression*. A regular expression is a set of special characters that define a pattern. My most frequent example of using `sed`

is replacing text in a file. The syntax for replacing text looks like this: `s/originaltext/newtext/`

. The `s`

tells sed to perform text replacement or swap occurrences of text. Provide the original text and new text between slashes.

This syntax will only replace the first occurrence of `originaltext`

on each line. To replace every occurrence, even if the original text appears more than once on a line, append `g`

to the end of the expression. Here is an example: `s/originaltext/newtext/g`

.

To use this with `sed`

, specify this regular expression with the `-e`

option:

```
````$ sed -e 's/originaltext/newtext/g'`


For example, let's say I have a Makefile for a program called **game**, which simulates Conway's Game of Life:

```
``````
.PHONY: all run clean
all: game
game: game.o
$(CC) $(CFLAGS) -o game game.o $(LDFLAGS)
run: game
./game
clean:
$(RM) *~
$(RM) *.o
$(RM) game
```


The name **game** isn't very descriptive, so I might choose to rename it **life**. Renaming the `game.c`

source file to `life.c`

is easy enough, but now I need to modify the Makefile to use the new name. I can use `sed`

to change every occurrence of **game** to **life**:

```
``````
$ sed -e 's/game/life/g' Makefile
.PHONY: all run clean
all: life
life: life.o
$(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
run: life
./life
clean:
$(RM) *~
$(RM) *.o
$(RM) life
```


This prints the `sed`

output to the screen, which is a good way to check if the text replacement will do what you want. To make these changes to the Makefile, first, make a backup of the file, then run `sed`

and save the output to the original filename:

```
``````
$ cp Makefile Makefile.old
$ sed -e 's/game/life/g' Makefile.old > Makefile
```


If you are confident that your changes are exactly what you want, use the `-i`

or `--in-place`

option to edit the file in place. However, I recommend adding a backup filename suffix like `--in-place=.old`

to save a copy of the original file in case you need to restore it later. It looks like this:

```
``````
$ sed --in-place=.old -e 's/game/life/g' Makefile
$ ls Makefile*
Makefile Makefile.old
```



## Quoting files with sed on Linux

You can use other features of regular expressions to match specific instances of text. For example, you might need to replace text that occurs at the start of a line. With `sed`

, you can match the beginning of a line with **^**, the caret character.

One way I use "start of line" in replacing text is when I need to quote a file in an email. Let's say I want to share my Makefile in an email, but I don't want to include it as a file attachment. Instead, I prefer to "quote" the file in the body of an email, using **>** before each line. I can use the following `sed`

command to print out an edited version to my terminal, which I can copy and paste into a new email:

```
``````
$ sed -e 's/^/>/' Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
> $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
> ./life
>
>clean:
> $(RM) *~
> $(RM) *.o
> $(RM) life
```


The `s/^/>/`

regular expression matches the start of each line (**^**) and places a **>** there. Effectively, this starts each line with the **>** symbol.

The tabs might not show up correctly in an email, but I can replace all tabs in the Makefile with a few spaces by adding another regular expression:

```
``````
$ sed -e 's/^/>/' -e 's/\t/ /g' Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
> $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
> ./life
>
>clean:
> $(RM) *~
> $(RM) *.o
> $(RM) life
```


The `\t`

indicates a literal tab, so `s/\t/ /g `

tells sed to replace all tabs in the input with two spaces in the output.

If you need to apply lots of edits to files, you can save your `-e`

commands in a file and use `-f`

to tell `sed`

to use that file as a "script." This approach is especially useful if you need to make the same edits frequently. I might have prepared the Makefile for quoting in email using a script file called `quotemail.sed`

:

```
``````
$ cat quotemail.sed
s/^/>/
s/\t/ /g
$ sed -f quotemail.sed Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
> $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
> ./life
>
>clean:
> $(RM) *~
> $(RM) *.o
> $(RM) life
```


## Learn to work with sed on Linux

`sed`

is a great tool to keep in your Linux command-line toolkit. Explore the `sed`

manual page and learn more about how to use it. Type `man sed`

at the command line to get complete documentation about the different command line options and how to use `sed`

to process text files.

## 4 Comments