Linux 流编辑

LinuxLinuxBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

欢迎来到 Linux 流编辑实验。在这个实验中,你将学习如何使用 sed(流编辑器),它是一个用于解析和转换文本的强大命令行工具。sed 用于对输入流(文件或来自管道的输入)执行基本的文本转换。

在本实验结束时,你将能够:

  • 使用 sed 执行基本的文本替换
  • 使用 sed 直接编辑文件
  • 在整个文件中应用全局替换
  • 使用高级文本处理技术

你所学的技能将帮助你高效地处理文件和文本流,这对于 Linux 中的各种系统管理和文本处理任务至关重要。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/BasicSystemCommandsGroup(["Basic System Commands"]) linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux(("Linux")) -.-> linux/TextProcessingGroup(["Text Processing"]) linux/BasicSystemCommandsGroup -.-> linux/echo("Text Display") linux/BasicFileOperationsGroup -.-> linux/cat("File Concatenating") linux/TextProcessingGroup -.-> linux/sed("Stream Editing") subgraph Lab Skills linux/echo -.-> lab-271375{{"Linux 流编辑"}} linux/cat -.-> lab-271375{{"Linux 流编辑"}} linux/sed -.-> lab-271375{{"Linux 流编辑"}} end

sed 的基本用法和文本替换

在这一步中,你将学习 sed 的基础知识以及如何执行简单的文本替换。sed 命令是一个强大的文本处理工具,它允许你在不使用编辑器打开文件的情况下,对文件中的文本进行搜索、查找和替换、插入以及删除操作。

首先,通过运行以下命令来验证系统上是否安装了 sed

which sed

你应该会看到类似如下的输出:

/usr/bin/sed

这表明 sed 已经可用。如果由于某种原因它未安装,你可以使用以下命令进行安装:

sudo apt-get update
sudo apt-get install -y sed

现在,让我们创建一个文本文件来进行操作。我们将在当前目录下创建一个名为 sample.txt 的文件:

echo "Linux is a powerful operating system." > ~/project/sample.txt
echo "Many users prefer Linux for servers." >> ~/project/sample.txt
echo "Linux has strong security features." >> ~/project/sample.txt

让我们查看新文件的内容:

cat ~/project/sample.txt

你应该会看到:

Linux is a powerful operating system.
Many users prefer Linux for servers.
Linux has strong security features.

现在,让我们使用 sed 进行基本的替换。以下命令将把每行中第一次出现的 "Linux" 替换为 "Ubuntu":

sed 's/Linux/Ubuntu/' ~/project/sample.txt

你应该会看到:

Ubuntu is a powerful operating system.
Many users prefer Ubuntu for servers.
Ubuntu has strong security features.

注意,sed 将修改后的文本输出到了标准输出(你的终端),但原始文件并未改变。你可以通过运行以下命令来验证:

cat ~/project/sample.txt

输出应该仍然显示 "Linux" 而不是 "Ubuntu":

Linux is a powerful operating system.
Many users prefer Linux for servers.
Linux has strong security features.

sed 替换的基本语法如下:

sed 's/pattern/replacement/' filename

其中:

  • s 是替换命令
  • pattern 是你想要替换的文本
  • replacement 是新的文本
  • filename 是输入文件

让我们再尝试一个例子。这次,我们将把 "powerful" 替换为 "versatile":

sed 's/powerful/versatile/' ~/project/sample.txt

输出应该如下:

Linux is a versatile operating system.
Many users prefer Linux for servers.
Linux has strong security features.

直接编辑和全局替换

在上一步中,你学习了如何使用 sed 进行基本的文本替换,但这些更改仅显示在屏幕上,并未保存到文件中。在这一步中,你将学习如何:

  1. 使用 -i 选项直接编辑文件
  2. 使用 g 标志执行全局替换

直接编辑

要使用 sed 对文件进行永久性更改,你可以使用 -i 选项。此选项会直接修改文件,而不是仅将输出打印到终端。

让我们通过将 "Linux" 替换为 "Ubuntu" 来修改 sample.txt 文件:

sed -i 's/Linux/Ubuntu/' ~/project/sample.txt

与上一步不同,此命令不会产生任何可见的输出。让我们检查文件内容,看看是否已更改:

cat ~/project/sample.txt

你现在应该会看到:

Ubuntu is a powerful operating system.
Many users prefer Ubuntu for servers.
Ubuntu has strong security features.

更改已保存到文件中!这就是使用 sed 进行直接编辑的强大之处。

全局替换

默认情况下,sed 仅替换每行中模式的第一次出现。要替换所有出现的模式,你可以在替换命令的末尾使用 g(全局)标志。

让我们创建一个包含重复文本的新文件:

echo "The red car stopped at the red light near the red building." > ~/project/colors.txt

现在,让我们在不使用全局标志的情况下,使用 sed 将 "red" 替换为 "blue":

sed 's/red/blue/' ~/project/colors.txt

你应该会看到:

The blue car stopped at the red light near the red building.

注意,只有 "red" 的第一次出现被替换为了 "blue"。现在,让我们使用全局标志:

sed 's/red/blue/g' ~/project/colors.txt

输出应该是:

The blue car stopped at the blue light near the blue building.

所有 "red" 的出现都已被替换为 "blue"!

让我们将此应用到 sample.txt 文件中。首先,让我们增加更多 "Ubuntu" 的出现次数:

echo "Ubuntu is great. I use Ubuntu daily for my work with Ubuntu tools." >> ~/project/sample.txt

现在,让我们使用全局标志和直接编辑,将所有 "Ubuntu" 的出现替换为 "Linux":

sed -i 's/Ubuntu/Linux/g' ~/project/sample.txt

让我们验证更改:

cat ~/project/sample.txt

你应该会看到:

Linux is a powerful operating system.
Many users prefer Linux for servers.
Linux has strong security features.
Linux is great. I use Linux daily for my work with Linux tools.

整个文件中所有 "Ubuntu" 的出现都已被替换为 "Linux"。

在直接编辑前创建备份

在使用直接编辑时,通常最好对原始文件进行备份。你可以通过为 -i 选项提供一个扩展名来实现这一点:

sed -i.bak 's/Linux/Ubuntu/g' ~/project/sample.txt

此命令将:

  1. sample.txt 备份为 sample.txt.bak
  2. sample.txt 中所有 "Linux" 的出现替换为 "Ubuntu"

让我们验证这两个文件:

cat ~/project/sample.txt
cat ~/project/sample.txt.bak

第一个命令应该显示所有 "Linux" 都已被替换为 "Ubuntu",而备份文件应该仍然包含 "Linux"。

高级 sed 命令和模式匹配

既然你已经掌握了使用 sed 进行基本替换和直接编辑的方法,接下来让我们探索一些更高级的特性:

  1. 使用不同的分隔符
  2. 使用地址范围来指定特定的行
  3. 组合多个命令

使用不同的分隔符

在之前的替换命令中,我们一直使用正斜杠 / 作为分隔符,但 sed 允许使用任何字符作为分隔符。当模式或替换文本中包含斜杠时,这一特性尤为有用。

让我们创建一个包含文件路径的文件:

echo "/usr/local/bin is in the PATH" > ~/project/paths.txt
echo "My config is in /etc/myapp/config.json" >> ~/project/paths.txt

如果你想将 /usr/local/bin 替换为 /opt/bin,使用斜杠会使命令变得混乱:

sed 's/\/usr\/local\/bin/\/opt\/bin/' ~/project/paths.txt

相反,你可以使用不同的分隔符,例如 #

sed 's#/usr/local/bin#/opt/bin#' ~/project/paths.txt

这样的命令可读性更强!输出应该是:

/opt/bin is in the PATH
My config is in /etc/myapp/config.json

其他常见的分隔符还包括 |:_

地址指定 - 针对特定行

sed 允许你指定要应用替换操作的行。这可以通过在命令前加上地址来实现。

让我们创建一个包含编号行的新文件:

echo "Line 1: This is the first line." > ~/project/numbered.txt
echo "Line 2: This is the second line." >> ~/project/numbered.txt
echo "Line 3: This is the third line." >> ~/project/numbered.txt
echo "Line 4: This is the fourth line." >> ~/project/numbered.txt
echo "Line 5: This is the fifth line." >> ~/project/numbered.txt

要仅在第 3 行将 "line" 替换为 "row",可以使用以下命令:

sed '3 s/line/row/' ~/project/numbered.txt

输出应该是:

Line 1: This is the first line.
Line 2: This is the second line.
Line 3: This is the third row.
Line 4: This is the fourth line.
Line 5: This is the fifth line.

你还可以指定行的范围。要在第 2 行到第 4 行将 "line" 替换为 "row",可以使用以下命令:

sed '2,4 s/line/row/' ~/project/numbered.txt

输出应该是:

Line 1: This is the first line.
Line 2: This is the second row.
Line 3: This is the third row.
Line 4: This is the fourth row.
Line 5: This is the fifth line.

另一个有用的特性是能够根据模式匹配行。例如,要仅在包含 "third" 或 "fourth" 的行上将 "line" 替换为 "row",可以使用以下命令:

sed '/\(third\|fourth\)/ s/line/row/' ~/project/numbered.txt

输出应该是:

Line 1: This is the first line.
Line 2: This is the second line.
Line 3: This is the third row.
Line 4: This is the fourth row.
Line 5: This is the fifth line.

组合多个命令

你可以使用 -e 选项或用分号分隔命令来组合多个 sed 命令。

让我们在一个命令中同时将 "first" 替换为 "1st"、"second" 替换为 "2nd" 以及 "third" 替换为 "3rd":

sed -e 's/first/1st/' -e 's/second/2nd/' -e 's/third/3rd/' ~/project/numbered.txt

或者,你也可以使用分号:

sed 's/first/1st/; s/second/2nd/; s/third/3rd/' ~/project/numbered.txt

这两个命令应该产生相同的输出:

Line 1: This is the 1st line.
Line 2: This is the 2nd line.
Line 3: This is the 3rd line.
Line 4: This is the fourth line.
Line 5: This is the fifth line.

现在,让我们将这些更改永久保存:

sed -i 's/first/1st/; s/second/2nd/; s/third/3rd/' ~/project/numbered.txt

并验证更改:

cat ~/project/numbered.txt

你应该会看到带有序数词的更新文本。

使用 sed 脚本

在前面的步骤中,你一直是直接从命令行运行 sed 命令。然而,对于更复杂的操作,创建一个 sed 脚本文件通常会更方便。这样做可以让你:

  1. 组织多个 sed 命令
  2. 添加注释来解释每个命令的作用
  3. 在不同的文件上重复使用相同的操作

创建 sed 脚本

让我们创建一个简单的 sed 脚本,它可以执行多个文本转换操作:

cat > ~/project/transform.sed << 'EOF'
## Replace "Linux" with "Ubuntu"
s/Linux/Ubuntu/g

## Replace "user" with "developer"
s/user/developer/g

## Replace "system" with "platform"
s/system/platform/g

## Convert "is" to uppercase
s/is/IS/g
EOF

这个脚本执行四项替换操作:

  1. 将所有“Linux”替换为“Ubuntu”
  2. 将所有“user”替换为“developer”
  3. 将所有“system”替换为“platform”
  4. 将所有“is”转换为大写的“IS”

让我们创建一个新文件来测试这个脚本:

cat > ~/project/test.txt << 'EOF'
Linux is a powerful operating system.
The user interface is very customizable.
Many Linux users prefer the command-line interface.
The system resources are efficiently managed.
EOF

运行 sed 脚本

要在测试文件上运行 sed 脚本,你可以使用 -f 选项:

sed -f ~/project/transform.sed ~/project/test.txt

你应该会看到:

Ubuntu IS a powerful operating platform.
The developer interface IS very customizable.
Many Ubuntu developers prefer the command-line interface.
The platform resources are efficiently managed.

脚本中的所有替换操作都已应用!

使用脚本进行直接编辑

就像使用命令行 sed 命令一样,你可以使用 -i 选项通过脚本来进行直接编辑:

sed -i -f ~/project/transform.sed ~/project/test.txt

让我们验证这些更改:

cat ~/project/test.txt

现在文件应该包含转换后的文本。

使用脚本创建备份

同样,你可以在进行更改之前创建备份:

## First, let's restore the original content
cat > ~/project/test.txt << 'EOF'
Linux is a powerful operating system.
The user interface is very customizable.
Many Linux users prefer the command-line interface.
The system resources are efficiently managed.
EOF

## Now run sed with a backup
sed -i.bak -f ~/project/transform.sed ~/project/test.txt

让我们检查修改后的文件和备份文件:

cat ~/project/test.txt
cat ~/project/test.txt.bak

第一个命令应该显示转换后的文本,而备份文件应该包含原始文本。

sed 脚本应用于多个文件

使用 sed 脚本的一个优点是,你可以轻松地将相同的转换操作应用于多个文件。

让我们再创建几个测试文件:

## Create test1.txt
cat > ~/project/test1.txt << 'EOF'
Linux offers excellent system performance.
Many users appreciate its stability.
EOF

## Create test2.txt
cat > ~/project/test2.txt << 'EOF'
The Linux community provides great support.
New users can find helpful resources online.
EOF

## Create test3.txt
cat > ~/project/test3.txt << 'EOF'
The system updates are well-managed in Linux.
Users can customize their experience.
EOF

现在,让我们一次性将 sed 脚本应用于所有这些文件:

sed -i -f ~/project/transform.sed ~/project/test1.txt ~/project/test2.txt ~/project/test3.txt

让我们验证这些更改:

cat ~/project/test1.txt
cat ~/project/test2.txt
cat ~/project/test3.txt

根据脚本,这三个文件都应该显示转换后的文本。

这展示了 sed 脚本在对多个文件进行批量处理相同转换操作时的强大功能。

总结

在本次实验中,你学习了如何使用 sed(流编辑器)在 Linux 系统中处理文本文件。你已经在 sed 的几个重要方面积累了实践经验:

  • 使用 s 命令进行基本的文本替换
  • 使用 -i 选项进行直接编辑
  • 使用 g 标志进行全局替换
  • 使用 -i.bak 选项在编辑前创建备份
  • 为替换模式使用不同的分隔符
  • 使用地址和范围指定特定的行
  • 创建并运行 sed 脚本来执行更复杂的操作
  • 一次性对多个文件应用转换操作

这些技能对于在 Linux 环境中进行高效的文本处理至关重要。无需在编辑器中打开文件就能处理文本文件的能力,对于经常需要处理大量文本数据或对多个文件进行系统性更改的系统管理员、开发人员和数据分析师来说尤其有价值。

随着你继续使用 Linux,你会发现 sed 是你文本处理工具包中不可或缺的工具,它与 grepawkcut 等其他实用工具一样重要。