如何在linux上使用sed命令

这听起来很疯狂,但是Linux sed命令是一个没有界面的文本编辑器。您可以从命令行使用它来操作文件和流中的文本。我们将向你展示如何利用它的力量。...

这听起来很疯狂,但是Linux sed命令是一个没有界面的文本编辑器。您可以从命令行使用它来操作文件和流中的文本。我们将向你展示如何利用它的力量。

sed的力量

sed命令有点像国际象棋:学习基础知识需要一个小时,掌握它们需要一辈子(或者,至少需要大量的练习)。我们将向您展示sed功能的每个主要类别中的一些开场白。

sed是一个流编辑器,可以处理管道输入或文本文件。但是,它没有交互式文本编辑器界面。更确切地说,您提供了它在阅读文本时要遵循的说明。这些都可以在Bash和其他命令行shell中使用。

使用sed,您可以执行以下所有操作:

  • 选择文本
  • 替换文本
  • 在文本中添加行
  • 从文本中删除行
  • 修改(或保留)原始文件

我们构建示例是为了介绍和演示概念,而不是生成最简洁(最不易接近)的sed命令。然而,sed的模式匹配和文本选择功能严重依赖正则表达式(regex)。你需要熟悉这些才能充分利用sed。

相关:如何在Linux上使用正则表达式(regex)

一个简单的例子

首先,我们将使用echo通过管道向sed发送一些文本,并让sed替换部分文本。为此,我们键入以下内容:

echo howtogonk | sed 's/gonk/geek/'

echo命令将“howtogonk”发送到sed,并应用我们的简单替换规则(“s”表示替换)。sed在输入文本中搜索第一个字符串的匹配项,并用第二个字符串替换任何匹配项。

字符串“gonk”被替换为“geek”,新字符串将在终端窗口中打印。

如何在linux上使用sed命令

替换可能是sed最常用的用法。不过,在深入研究替换之前,我们需要知道如何选择和匹配文本。

选择文本

我们的例子需要一个文本文件。我们将使用一个包含选自塞缪尔·泰勒·柯勒律治史诗《古代水手的雾凇》的诗句

我们键入以下内容,以便用更少的信息查看它:

less coleridge.txt

如何在linux上使用sed命令

要从文件中选择一些行,我们提供要选择的范围的开始行和结束行。一个数字选择那一行。

要提取第1行到第4行,请键入以下命令:

sed -n '1,4p' coleridge.txt

注意1和4之间的逗号。p表示“打印匹配行”。默认情况下,sed打印所有行。我们会看到文件中所有的文本都打印了两次匹配的行。为了防止这种情况,我们将使用-n(quiet)选项来抑制不匹配的文本。

我们更改行号以便选择不同的诗句,如下所示:

sed -n '6,9p' coleridge.txt

如何在linux上使用sed命令

我们可以使用-e(表达式)选项进行多个选择。用两种表达方式,我们可以选择两首诗,如下所示:

sed -n -e '1,4p' -e '31,34p' coleridge.txt

如果我们减少第二个表达式中的第一个数字,我们就可以在两节之间**一个空格。我们键入以下内容:

sed -n -e '1,4p' -e '30,34p' coleridge.txt

如何在linux上使用sed命令

我们也可以选择一个起始行,告诉sed遍历文件并每隔五行打印一行,或者跳过任意数量的行。该命令类似于我们上面用来选择范围的命令。不过,这次我们将使用波浪号(~)而不是逗号来分隔数字。

第一个数字表示起跑线。第二个数字告诉sed我们想看的是起跑线之后的哪一行。数字2表示每第二行,3表示每第三行,依此类推。

我们键入以下内容:

sed -n '1~2p' coleridge.txt

如何在linux上使用sed命令

您不一定知道要查找的文本在文件中的位置,这意味着行号不会总是有太大帮助。但是,也可以使用sed来选择包含匹配文本模式的行。例如,让我们提取所有以“And”开头的行

**符号(^)表示行的开始。我们将搜索词用正斜杠(/)括起来。我们还在“和”后面加了一个空格,所以像“Android”这样的词不会出现在结果中。

阅读sed脚本一开始可能有点困难。p的意思是“打印”,就像我们在上面使用的命令中一样。但是,在下面的命令中,前面有一个正斜杠:

sed -n '/^And /p' coleridge.txt

如何在linux上使用sed命令

从文件中提取并显示以“And”开头的三行。

替换

在第一个示例中,我们向您展示了sed替换的以下基本格式:

echo howtogonk | sed 's/gonk/geek/'

s告诉sed这是一个替代品。第一个字符串是搜索模式,第二个字符串是要替换匹配文本的文本。当然,就像所有的Linux一样,魔鬼在细节中。

我们键入以下内容以将所有出现的“日”更改为“周”,并给水手和信天翁更多的时间来联系:

sed -n 's/day/week/p' coleridge.txt

在第一行中,只有第二个出现的“day”被更改。这是因为sed在每行的第一场比赛后停止。我们必须在表达式末尾添加一个“g”,如下所示,以执行全局搜索,从而处理每行中的所有匹配项:

sed -n 's/day/week/gp' coleridge.txt

这与第一行的四分之三相符。因为第一个单词是“Day”,sed是区分大小写的,所以它不认为该实例与“Day”相同

我们键入以下内容,在表达式末尾的命令中添加一个i以表示不区分大小写:

sed -n 's/day/week/gip' coleridge.txt

这是可行的,但您可能并不总是希望对所有内容都启用不区分大小写。在这些情况下,可以使用regex组添加特定于模式的大小写不敏感。

例如,如果我们将字符括在方括号([])中,它们将被解释为“此字符列表中的任何字符”

我们键入以下内容,并在组中包含“D”和“D”,以确保它同时匹配“Day”和“Day”:

sed -n 's/[Dd]ay/week/gp' coleridge.txt

如何在linux上使用sed命令

我们还可以将替换限制为文件的部分。假设我们的档案第一节有奇怪的间隔。我们可以使用以下熟悉的命令来查看第一节:

sed -n '1,4p' coleridge.txt

我们将搜索两个空格并用一个替换它们。我们将在全球范围内执行此操作,以便在整个生产线中重复此操作。要清楚的是,搜索模式是空格,空格星号(*),替换字符串是单个空格。1,4将替换限制为文件的前四行。

我们将所有这些放在下面的命令中:

sed -n '1,4 s/ */ /gp' coleridge.txt

这个很好用!搜索模式在这里很重要。星号(*)表示前面的零个或多个字符,即空格。因此,搜索模式是寻找一个或多个空格的字符串。

如果我们用一个空格替换多个空格的任意序列,我们会将文件返回到规则的空格,每个单词之间只有一个空格。在某些情况下,这也会用一个空格代替一个空格,但这不会对任何东西产生不利影响,我们仍然可以得到我们想要的结果。

如果我们键入以下内容并将搜索模式缩减为单个空格,您将立即看到为什么必须包含两个空格:

sed -n '1,4 s/ */ /gp' coleridge.txt

如何在linux上使用sed命令

因为星号匹配前面的零个或多个字符,所以它将每个不是空格的字符视为“零空格”,并对其应用替换。

但是,如果在搜索模式中包含两个空格,sed必须在应用替换之前找到至少一个空格字符。这样可以确保非空格字符保持不变。

我们使用前面使用的-e(表达式)键入以下内容,它允许我们同时进行两个或多个替换:

sed -n -e 's/motion/flutter/gip' -e 's/ocean/gutter/gip' coleridge.txt

如果我们用分号(;)来分隔这两个表达式,我们可以得到相同的结果,如下所示:

sed -n 's/motion/flutter/gip;s/ocean/gutter/gip' coleridge.txt

如何在linux上使用sed命令

在下面的命令中将“day”替换为“week”时,表达式“well a-day”中的“day”实例也被替换:

sed -n 's/[Dd]ay/week/gp' coleridge.txt

为了防止这种情况,我们只能尝试在与另一个模式匹配的行上进行替换。如果我们修改命令,使之在开始时有一个搜索模式,我们将只考虑在与该模式匹配的行上进行操作。

我们键入以下内容使匹配模式成为单词“after”:

sed -n '/after/ s/[Dd]ay/week/gp' coleridge.txt

这给了我们想要的回应。

如何在linux上使用sed命令

更复杂的替换

让我们让Coleridge休息一下,然后使用sed从etc/passwd文件中提取名称。

有一些较短的方法可以做到这一点(稍后将详细介绍),但我们将在这里使用较长的方法来演示另一个概念。搜索模式中的每个匹配项(称为子表达式)都可以编号(最多九个项)。然后可以在sed命令中使用这些数字来引用特定的子表达式。

必须将子表达式括在括号[()]中,才能使其工作。括号前面还必须加一个反斜杠(\),以防止它们被视为普通字符。

为此,请键入以下内容:

sed 's/\([^:]*\).*/\1/' /etc/passwd

如何在linux上使用sed命令

我们来分解一下:

  • sed's/:sed命令和替换表达式的开头。
  • \(:包含子表达式的左括号[(],前面有反斜杠(\)。
  • [^:]*:搜索项的第一个子表达式包含方括号中的组。**符号(^)在组中使用时表示“不”。组表示任何不是冒号(:)的字符都将被接受为匹配项。
  • \):右括号[)]前面有反斜杠(\)。
  • .*:第二个搜索子表达式表示“任意字符和任意数量的字符”
  • /\1:表达式的替换部分包含1,前面有反斜杠(\)。这表示与第一个子表达式匹配的文本。
  • /':右正斜杠(/)和单引号(')终止sed命令。

这意味着我们要查找任何不包含冒号(:)的字符串,冒号将是匹配文本的第一个实例。然后,我们在该行中搜索其他内容,这将是匹配文本的第二个实例。我们将用与第一个子表达式匹配的文本替换整行。

/etc/passwd文件中的每一行都以冒号结尾的用户名开头。我们将所有内容匹配到第一个冒号,然后用该值替换整行。所以,我们已经隔离了用户名。

如何在linux上使用sed命令

接下来,我们将第二个子表达式括在括号[()]中,这样我们也可以通过数字引用它。我们还将用\2替换\1。现在,我们的命令将用从第一个冒号(:)到行尾的所有内容替换整行。

我们键入以下内容:

sed 's/\([^:]*\)\(.*\)/\2/' /etc/passwd

如何在linux上使用sed命令

这些小小的改变改变了命令的含义,我们得到了除了用户名之外的所有东西。

如何在linux上使用sed命令

现在,让我们看看快速简便的方法。

我们的搜索词是从第一个冒号(:)到行尾。因为替换表达式为空(//),所以我们不会用任何内容替换匹配的文本。

因此,我们键入以下内容,切掉从第一个冒号(:)到行尾的所有内容,只留下用户名:

sed 's/:.*//" /etc/passwd

如何在linux上使用sed命令

让我们看一个例子,在这个例子中,我们在同一个命令中引用第一个和第二个匹配项。

我们有一个用逗号(,)分隔名字和姓氏的文件。我们希望将它们列为“姓,名”。我们可以使用cat查看文件中的内容,如下所示:

cat geeks.txt

与许多sed命令一样,下一个命令一开始可能看起来难以穿透:

sed 's/^\(.*\),\(.*\)$/\2,\1 /g' geeks.txt

如何在linux上使用sed命令

这是一个与我们使用的其他命令类似的替换命令,搜索模式非常简单。我们将其分解如下:

  • sed的/:正常的替换命令。
  • ^:因为**符号不在组([])中,所以它表示“行的开始”
  • \(.*\),:第一个子表达式是任意字符数。它被括在括号[()]中,每个括号前面都有一个反斜杠(\),所以我们可以用数字来引用它。到目前为止,我们的整个搜索模式都是从行的开始到第一个逗号(,)搜索任意数量的字符。
  • \(.*\):下一个子表达式(同样)是任意字符的任意数。它也包含在括号[()]中,两个括号前面都有反斜杠(\),因此我们可以按数字引用匹配的文本。
  • $/:美元符号($)表示行尾,允许我们继续搜索行尾。我们用这个简单地介绍了美元符号。在这里我们并不需要它,因为在这个场景中星号(*)会出现在行的末尾。正斜杠(/)完成搜索模式部分。
  • \2、\1/g':因为我们将两个子表达式括在括号中,所以我们可以用它们的数字来引用它们。因为我们想颠倒顺序,所以我们把它们输入为第二个匹配,第一个匹配。数字前面必须加反斜杠(\)。
  • /g:这使我们的命令可以在每一行上全局工作。
  • 极客.txt:我们正在处理的文件。

也可以使用“剪切”命令(c)替换与搜索模式匹配的整行。我们键入以下内容以搜索包含单词“neck”的行,并将其替换为新的文本字符串:

sed '/neck/c Around my wrist was strung' coleridge.txt

如何在linux上使用sed命令

我们的新行现在出现在摘录的底部。

如何在linux上使用sed命令

**行和文本

我们还可以在文件中**新行和文本。要在任何匹配的行之后**新行,我们将使用Append命令(a)。

下面是我们要处理的文件:

猫极客.txt

如何在linux上使用sed命令

我们已经对线路进行了编号,以便更容易理解。

我们键入以下内容以搜索包含单词“He”的行,并在其下方**新行:

sed '/He/a --> Inserted!' geeks.txt

如何在linux上使用sed命令

我们键入以下命令,并包括**命令(i)以在包含匹配文本的行上方**新行:

sed '/He/i --> Inserted!' geeks.txt

如何在linux上使用sed命令

我们可以使用表示原始匹配文本的与号(&)将新文本添加到匹配行。\1、\2等表示匹配的子表达式。

要将文本添加到行的开头,我们将使用一个与行上的所有内容匹配的替换命令,并结合一个将新文本与原始行相结合的替换子句。

要执行所有这些操作,请键入以下内容:

sed 's/.*/--> Inserted &/' geeks.txt

如何在linux上使用sed命令

我们键入以下命令,包括G命令,它将在每行之间添加一个空行:

sed 'G' geeks.txt

如何在linux上使用sed命令

如果要添加两个或多个空行,可以使用G;G,G;G;G,依此类推。

删除行

Delete命令(d)删除与搜索模式匹配的行,或使用行号或范围指定的行。

例如,要删除第三行,请键入以下内容:

sed '3d' geeks.txt

要删除第四行到第五行的范围,请键入以下内容:

sed '4,5d' geeks.txt

要删除范围之外的行,我们使用感叹号(!),如下图:

sed '6,7!d' geeks.txt

如何在linux上使用sed命令

保存更改

到目前为止,我们所有的结果都已打印到终端窗口,但我们还没有将它们保存到任何地方。要使这些文件永久化,可以将更改写入原始文件,也可以将更改重定向到新文件。

覆盖原始文件需要谨慎。如果sed命令错误,可能会对原始文件进行一些难以撤消的更改。

为了让您放心,sed可以在执行命令之前创建原始文件的备份。

您可以使用In-place选项(-i)告诉sed将更改写入原始文件,但如果向其添加文件扩展名,sed将把原始文件备份到新文件。它将具有与原始文件相同的名称,但具有新的文件扩展名。

为了演示,我们将搜索任何包含单词“He”的行并删除它们。我们还将使用BAK扩展名将原始文件备份到新文件。

要执行所有这些操作,请键入以下内容:

sed -i'.bak' '/^.*He.*$/d' geeks.txt

我们键入以下内容以确保备份文件不变:

cat geeks.txt.bak

如何在linux上使用sed命令

我们还可以键入以下命令将输出重定向到新文件并获得类似的结果:

sed -i'.bak' '/^.*He.*$/d' geeks.txt > new_geeks.txt

我们使用cat来确认更改已写入新文件,如下所示:

cat new_geeks.txt

如何在linux上使用sed命令

把这一切都抹掉了

正如您可能已经注意到的,即使是sed上的快速入门也相当长。这个命令有很多,你可以用它做更多的事情。

然而,希望这些基本概念为你继续学习更多的知识奠定了坚实的基础。

  • 发表于 2021-04-02 08:03
  • 阅读 ( 154 )
  • 分类:互联网

你可能感兴趣的文章

如何在linux上安装和使用powershell

... 在本文中,我将向您展示如何在Linux上安装、运行和使用PowerShell! ...

  • 发布于 2021-03-16 02:34
  • 阅读 ( 307 )

如何从usb启动raspberry pi 3

...的USB硬盘驱动器。这是一个重要的发展,所以让我们看看如何设置你的树莓皮3从USB启动。 ...

  • 发布于 2021-03-17 12:42
  • 阅读 ( 239 )

如何在windows10上获得linux bash shell

... 如何在windows10上安装linux bash shell ...

  • 发布于 2021-03-21 11:48
  • 阅读 ( 284 )

如何在linux中添加用户

想在Linux系统上添加用户但不知道如何添加?在Linux上使用命令行界面管理用户无疑是一项复杂的工作。而对于初学者来说,即使添加新用户也是一场噩梦。 ...

  • 发布于 2021-03-26 23:29
  • 阅读 ( 334 )

如何在linux上使用rev命令

...,它没有排列,但不,这还不算全部。本教程将向您展示如何将其组合起来进行强大的操作。 当您在更复杂的命令序列中使用rev作为构建块时,它真正开始显示出它的价值。rev是一组作为促进者的命令(比如tac和yes)之一。当...

  • 发布于 2021-04-03 07:47
  • 阅读 ( 212 )

如何列出mac上的所有应用程序

...app文件,所以您可以更轻松地在硬盘上移动它们。以下是如何找到你失去的人。 从应用程序文件夹 这个方法很明显只要打开你的应用程序文件夹。您通常可以在侧边栏、硬盘顶部或主文件夹(上面有您名字的文件夹)中找到...

  • 发布于 2021-04-03 17:06
  • 阅读 ( 120 )

如何使用bash从subreddit中获取主题列表

Reddit为每个subreddit提供JSON提要。下面是如何创建一个Bash脚本,从您喜欢的任何subreddit下载并解析帖子列表。这只是Reddit的JSON提要可以做的一件事。 安装卷曲和jq 我们将使用curl从Reddit和jq获取JSON提要,解析JSON数据并从结果中...

  • 发布于 2021-04-03 18:06
  • 阅读 ( 207 )

windows10的新bashshell所能做的一切

...些指南汇总到一个大列表中。 windows上linux入门 相关:如何在windows10上安装和使用Linux Bash Shell 您可以在任何版本的windows10(包括windows10home)上安装Linux环境和bashshell。但是,它确实需要64位版本的Windows10。您只需启用Windows Subs...

  • 发布于 2021-04-06 14:44
  • 阅读 ( 264 )

如何在windows10上安装和使用linux bash shell

...令行应用程序都能正常工作,因为这个特性并不完美。 如何在windows10上安**ash 相关:如何知道我运行的是32位还是64位Windows? 此功能在32位版本的Windows 10上不起作用,因此请确保您使用的是64位版本的Windows。无论如何,如果你...

  • 发布于 2021-04-06 16:32
  • 阅读 ( 248 )

如何在Windows10上设置默认的linux发行版

...个Linux环境,可以设置默认值并在它们之间切换。 相关:如何在windows10上安装和使用Linux Bash Shell 您可以自由地一次运行多个Linux环境,但是当您运行类似wsl.exe文件或者bash.exe启动shell,或者使用wsl[command]或bash-c[command]从Windows中...

  • 发布于 2021-04-06 16:40
  • 阅读 ( 198 )
铁头天吴
铁头天吴

0 篇文章

相关推荐