使用 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+ 次瀏覽

開啟您的職業生涯

透過完成課程獲得認證

立即開始
廣告