网站内容复制(了解Linux流编辑器streameditor)
优采云 发布时间: 2022-02-27 23:13网站内容复制(了解Linux流编辑器streameditor)
了解 sed 的基础知识,然后下载我们的备忘单,以便快速轻松地参考 Linux 流编辑器。
很少有 Unix 命令像 sed、grep 和 awk 这样著名,它们经常组合在一起,可能是因为它们的奇怪名称和强大的文本解析能力。它们也有一些句法和逻辑上的相似之处。虽然它们都可以用于文本解析,但它们都有自己的特点。本文研究 sed 命令,它是一个流编辑器。
我以前写过关于 sed 及其远亲 ed 的 文章。要熟悉 sed,了解一点 ed 会很有帮助,因为这将帮助您熟悉缓冲区的概念。本文假设您熟悉 sed 的基础知识,这意味着您至少已经运行了经典的 s/foo/bar 样式的查找和替换命令。
安装 sed
如果您使用的是 Linux、BSD 或 macOS,它们已经安装了 GNU 或 BSD 的 sed。这些是原创 sed 命令的独特重新实现。虽然它们相似,但也有一些细微的差别。本文已经在 Linux 和 NetBSD 版本上进行了测试,因此您可以使用您在计算机上找到的任何 sed,但对于 BSD sed,您必须使用短选项(例如 -n 而不是 --quiet)。
GNU sed 通常被认为是功能最丰富的 sed,因此无论您是否运行 Linux,您都可能想尝试一下。如果在 Ports 树中找不到 GNU sed(在非 Linux 系统上通常称为 gsed),您可以从 GNU 网站 下载源代码。安装 GNU sed 的好处是您可以使用它的额外功能,但如果您需要可移植性,您也可以限制它以符合 sed 的 POSIX 规范。
MacOS 用户可以在 MacPorts 或 Homebrew 上找到 GNU sed。
在 Windows 上,您可以通过 Chocolatey 安装 GNU sed。
了解模式空间和保留空间
sed 一次只能处理一行。因为它没有视觉模式,所以它创建了一个模式空间模式空间,这是一个收录来自输入流的当前行的内存空间(删除了任何尾随的换行符)。填充模式空间后,sed 将执行您的指令。当命令执行完成时,sed 将模式空间的内容打印到输出流,默认为标准输出,但输出可以重定向到一个文件,甚至可以通过 --in-place= 重定向到同一个文件.bak 选项。
然后,循环再次从下一个输入行开始。
为了在遍历文件时提供一点灵活性,sed 还提供了保持空间(有时称为保持缓冲区),这是 sed 内存中为临时数据存储保留的空间。您可以将保留空间视为剪贴板,实际上,这正是本文所演示的内容:如何使用 sed 进行复制/剪切和粘贴。
首先,创建一个收录以下内容的示例文本文件:
Line one
Line three
Line two
将数据复制到保留空间
要将内容放在 sed 的保留空间中,请使用 h 或 H 命令。小写的 h 告诉 sed 覆盖当前在保留空间中的内容,而大写的 H 告诉 sed 将数据附加到已在保留空间中的内容。
单独使用,你什么都看不到:
$ sed --quiet -e '/three/ h' example.txt
$
--quiet(缩写为 -n)选项会抑制所有输出,但 sed 会执行我需要搜索的操作。在这种情况下,sed 选择任何收录字符串 3 的行并将其复制到保留空间。我没有告诉 sed 打印任何东西,所以没有输出。
从保留空间复制数据
要了解保留空间,您可以从保留空间中复制内容,然后使用 g 命令将其放入模式空间并观察会发生什么:
$ sed -n -e '/three/h' -e 'g;p' example.txt
Line three
Line three
第一个空行是因为sed第一次将内容复制到模式空间时,保留的空间是空的。
接下来的两行收录第三行,因为这是第二行的保留空间。
该命令使用两个独特的脚本 (-e) 纯粹是为了帮助提高可读性和组织性。将这些步骤分成单独的脚本可能很有用,但从技术上讲,以下命令与单个脚本语句一样有效:
$ sed -n -e '/three/h ; g ; p' example.txt
Line three
Line three
将数据附加到模式空间
G 命令将在模式空间中添加一个换行符和保留空间的内容。
$ sed -n -e '/three/h' -e 'G;p' example.txt
Line one
Line three
Line three
Line two
Line three
此输出的前两行收录模式空间(第一行)的内容和一个空的保留空间。接下来的两行匹配搜索文本(三),因此它收录模式空间和保留空间。第三行的保留空间不变,所以在模式空间的末尾(第二行)是保留空间(仍然是第三行)。
用 sed 剪切和粘贴
现在您知道如何将字符串从模式空间转移到保留空间并再次返回,您可以设计一个 sed 脚本来复制、删除和粘贴文档中的一行。比如把示例文件的第三行移到第三行,sed就可以解决这个问题:
$ sed -n -e '/three/ h' -e '/three/ d' \
-e '/two/ G;p' example.txt
Line one
Line two
Line three
任务完成。
使用 sed 编写脚本
同样,使用单独的脚本语句纯粹是为了视觉和心理上的简单性。剪切和粘贴命令也可以作为脚本使用:
$ sed -n -e '/three/ h ; /three/ d ; /two/ G ; p' example.txt
Line one
Line two
Line three
它甚至可以写在一个专用的脚本文件中:
#!/usr/bin/sed -nf
/three/h
/three/d
/two/ G
p
要运行脚本,请使其可执行并使用示例文件进行尝试:
$ chmod +x myscript.sed
$ ./myscript.sed example.txt
Line one
Line two
Line three
当然,您需要解析的文本越可预测,使用 sed 解决问题就越容易。为 sed 操作(例如复制和粘贴)发明“配方”通常是不切实际的,因为触发操作的条件可能因文件而异。但是,您对 sed 命令越熟练,就越容易根据需要解析的输入设计复杂的操作。
重要的是识别不同的操作,知道 sed 何时移动到下一行,并预测模式和保留空间将收录什么。
下载备忘单
sed 很复杂。虽然它只有十几个命令,但其灵活的语法和原生特性意味着它充满了无限的潜力。为了充分利用 sed,我曾经提到过一些简洁的单行命令,但直到我开始发明(有时是重新发明)我自己的解决方案时,我才觉得自己真正开始学习 sed。如果您正在寻找有关命令提示符和语法的有用提示,请下载我们的 sed 备忘单并一劳永逸地开始学习 sed!
通过:
作者:Seth Kenlon 题目:lujun9972 译者:MjSeven 校对:wxy
本文由LCTT原创编译,Linux中国荣幸推出