Text-Processing

在匹配模式之後返回多行文件中的一行字元串

  • October 1, 2021

我有一個包含多行的文件。我正在嘗試獲取出現在特定模式之後的字元串…

這是我要執行的命令:

sed -n -e 's/^.*DB_PASS=//p' <<< $(cat /root/dadosDB)

但不是只給我我想要的線,而是在我指定的模式之後給我一切……

我的期望:

僅返回包含DB_PASS並忽略其他行的行的輸出。

命令在做什麼:

在該模式之後列印整個文件的所有DB_PASS內容並忽略該模式之前出現的所有內容。

任何幫助都是欣賞它!

這是我裡面的東西dadosDB

DB_USER=myusername
DB_PASS=mypassword
DB_NAME=mydatabase

我只想得到之後的內容DB_PASS=並停在該行,而忽略以下內容。

的實際輸出sed

$ sed -n 's/^.*DB_PASS=//p' <<< $(cat /root/dadosDB)
mypassword DB_NAME=mydatabase

我需要的:

mypassword

你得到這個結果的原因是你沒有將sed命令直接應用到文件,而是應用到命令替換的結果。

這意味著文本處理實際上並未應用於

DB_USER=myusername
DB_PASS=mypassword
DB_NAME=mydatabase

但是對於cat應用於文件內容的命令的結果,在擠壓行的不帶引號的命令替換之後。

如果你試試

echo $(cat /root/dadosDB)

你會注意到輸出是

DB_USER=myusername DB_PASS=mypassword DB_NAME=mydatabase

都在一行上,而不是在單獨的行上。如果將命令替換放在雙引號中,如

echo "$(cat /root/datosDB)"

換行符將被保留。

關鍵點是

  1. 您既不需要 thecat也不需要命令替換,並且
  2. 如果您使用命令替換而不將其放在雙引號中,您將失去換行符(參見此問答,例如)。(1)

TL;博士:

利用

sed -n -e 's/^.*DB_PASS=//p' /root/dadosDB

更確切地說)

sed -n -e 's/^DB_PASS=//p' /root/dadosDB

排除具有不同開頭但以.結尾的關鍵字的行DB_PASS

請注意:您寫*“並停在該行,忽略以下行”。我認為這意味著您要在之後列印單詞DB_PASS*,而不是以下行(從技術上講,這也是在 之後DB_PASS。如果您的意思是可能有更多行以開頭DB_PASS並且您想確保僅匹配第一行,您將需要輕微調整:

sed -n -e '0,/DB_PASS/s/^DB_PASS=//p' /root/dadosDB

(1)請注意,在您的特定情況下,問題是您的外殼(我假設 Bash)如何使用未引用的替換處理“Here-strings”,因此(如@steeldriver 所述)更好的展示是

cat <<< "$(cat /root/dadosDB)"

對比

cat <<< $(cat /root/dadosDB)

Bash v4.4的行為發生了變化:之前,這兩個命令的輸出與echo上面提到的範例相同。在更高版本的 Bash 中,不帶引號的命令替換將不再導致分詞和隨之而來的多行輸出壓縮。


如果你有興趣了解更多,你可能想看看

此外,我建議使用 來檢查您的腳本shellcheck,它也可作為許多 Linux 發行版上的獨立工具使用,以避免語法(和其他)錯誤。

引用自:https://unix.stackexchange.com/questions/670996