使用 Linux bash 提取子字符串


概述

从字符串中提取子字符串是 Linux 中文本处理的基本且常见的操作。

我们在这里研究了使用 Linux 命令行从字符串中提取子字符串的不同方法。

提取基于索引的子字符串

让我们首先快速了解一下如何使用四种不同的方法提取基于索引的子字符串。

  • 使用cut命令

  • 使用awk命令

  • 使用 Bash 的子字符串扩展

  • 使用expr命令

接下来,我们将看到它们在实际中的应用。

使用 cut 命令

我们可以使用 "cut" 命令从输入字符串中提取从位置 N 到位置 M 的字符。

要使用 cut 命令解决我们的问题,我们必须将起始索引加 1,并将结束索引减 1。因此,新的区间将分别为 4-8 和 9-13。

现在,我们将看看 cut 命令是否解决了问题。

$ cut -c 5-9 <<< '0123Linux9'
Linux

我们找到了预期的子字符串“Linux”——不再是问题。

我们将输入字符串通过 here-string 传递给我们的 cut 函数,然后回显结果。

使用awk命令

如果我们想解决 Linux 中的一些文本处理问题,我们不需要记住任何特定的工具。我们只需要使用 awk。

substr() 函数接受三个参数。让我们详细检查一下每个参数。

  • s - 输入字符串

  • i - 子字符串的起始索引(awk 使用基于 1 的索引系统

  • n - 子字符串的长度。如果省略,awk 将从索引 i 返回到输入字符串中的最后一个字符作为子字符串

现在让我们看看 awk 的 substring() 函数是否能为我们提供所需的输出。

$ awk '{print substr($0, 5, 5)}' <<< '0123Linux9'
Linux

我们从位置 0(第一个字符)开始,一直计数到位置 4(最后一个字符)。然后我们加 1 以说明我们从 1 而不是 0 开始计数。

使用 Bash 的子字符串扩展

我们已经看到了 cut 和 awk 如何轻松地提取类似子字符串的字符串。

不要使用不支持子字符串扩展的 sed,而应使用支持它的 bash。

如今,bash 是大多数现代 Linux 发行版的默认命令行解释器。换句话说,如果我们想使用命令行,我们不需要安装任何其他东西。

$ STR="0123Linux9"
$ echo ${STR:4:5}
Linux

使用expr命令

expr(表达式)是 GNU Core Utilities 包中的一个核心实用程序。这意味着它可用于所有 Linux 系统。

此外,expr 有一个名为 substr 的子命令,它允许我们从表达式中提取子字符串。

expr substr <input_string> <start_index> <length>

您可能需要提到 expr 函数使用基于 1 的索引系统。

假设我们想从每一行文本中提取前两个单词。我们可以将 substring 函数与

$ expr substr "0123Linux9"5 5
Linux

以上输出表明 expr 解决方案有效。

提取基于模式的子字符串

现在,除了我们已经学习过的基于索引的子字符串之外,我们还将探讨模式子字符串。

我们将讨论两种解决问题的方法:一种方法,我们将

  • 使用 cut 命令

  • 使用 awk 命令

我们将通过查看不同类型的字符串匹配问题来采用另一种方法来解决此问题。

使用cut命令

"字段"命令是用于处理与字段相关数据的有用工具。

让我们快速了解一下我们的问题。我们有一个用逗号分隔的输入值。我们想从该列表中获取第三个项目。

我们可以使用 awk 以逗号(,-)作为分隔符将行分割成字段,然后打印出第三个字段(-f3)。

$ cut -d , -f 3 <<< "Eric,Male,28,USA"
28

我们实现了我们期望的结果并解决了问题。

使用awk命令

Awk 也擅长处理基于字段的输入。一个简洁的 awk 单行命令可以解决此问题。

$ awk -F',' '{print $3}' <<< "Eric,Male,28,USA"
28

此外,由于 awk 的字段分隔符 (FS) 允许使用正则表达式,因此我们可以使用 awk 构建更通用的解决方案。

因此,“C”选项不是解决此问题的最佳选择。它仅支持一个字符作为字段分隔符。

使用 awk 仍然很容易。

$ awk -F', ' '{print $3}' <<< "Eric, Male, 28, USA"
28

您可以在两种情况下都使用 awk 命令。这在现实世界中可能是一个方便的技巧。

$ awk -F', ?' '{print $3}' <<< "Eric, Male, 28, USA"
28
$ awk -F', ?' '{print $3}' <<< "Eric,Male,28,USA"
28

不同的基于模式的子字符串案例

我们已经处理了“Eric 的生日”问题。现在让我们看看另一个问题。

虽然从理论上讲,基于模式的子字符串应该存在于 CSV 文件中,但这并不总是如此。为了演示,让我们看一个例子。

Awk 是解决此类挑战的极佳工具。但是,它并不总是使用 cut 命令。

现在让我们看看如何使用 awk 解决此问题。我们将输入字符串存储到名为 $STR 的变量中,以便我们的命令更易于阅读。

$ STR="whatever dataBEGIN:Interesting dataEND:something else"
$ awk -F'BEGIN:|END:' '{print $2}' <<< "$STR"
Interesting data
$ awk '{ sub(/.*BEGIN:/, ""); sub(/END:.*/, ""); print }' <<< "$STR"
Interesting data

第一个 awk 语句将每一行的开头(或结尾)设置为分隔符,然后获取第二列。

执行这两个替换后,我们的最终输出将是我们想要的。我们只需要显示它。

结论

文本处理是 Linux 的关键组成部分。根据需要,可以通过模式或索引相关的参数确定特定的子字符串。

通过示例,我们研究了如何从这两种类型的字符串中提取子字符串。

更新于:2023年1月3日

6K+ 次浏览

开启您的职业生涯

通过完成课程获得认证

立即开始
广告