我有一個字串,需要從中提取子字串,但正規表示式的末尾是重複的。我希望 sed 在正規表示式末尾的第一個實例處停止,就像許多語言中的 instr() 函數會傳回第一個實例一樣。例子:
echo "This is a test some stuff I want string junk string end" | sed -n 's/.*\(.te.*ng\).*/\1/p'
returns: test some stuff I want string junk string
I want to return: test some stuff I want string
答案1
grep方法(需要聚合酶鍊式反應支持):
s="This is a test some stuff I want string junk string end"
grep -Po 'te.*?ng' <<< $s
選擇珀爾方法:
perl -ne 'print "$&\n" if /te.*?ng/' <<< $s
輸出(兩種方法):
test some stuff I want string
.*?
-?
這是非貪婪修飾符,告訴匹配極簡時尚
答案2
分兩步驟進行:先刪除前綴(如果前綴中存在終止符),然後刪除前綴後面的所有內容。如果不匹配,使用T
命令跳過一行:
echo "This is a test some stuff I want string junk string end" |
sed -n 's/.*\(.te.*ng\)/\1/; T; s/\(ng\).*/\1/p'
或者,先刪除不符合的行,然後隨意執行替換。
echo "This is a test some stuff I want string junk string end" |
sed '/.*\(.te.*ng\)/!d; s/.*\(.te.*ng\)/\1/; s/\(ng\).*/\1/'
或者,僅在匹配的行上執行替換和最終列印。
echo "This is a test some stuff I want string junk string end" |
sed '/.*\(.te.*ng\)/ { s/.*\(.te.*ng\)/\1/; s/\(ng\).*/\1/p; }'
答案3
我建議在你的情況下使用 cut 指令
echo "I am a useful and I am a string. Did I mention that I'm a string?" | cut -d "string" -f1
這會將字串切割成三部分(第一部分之前,第二部分之後。以及「字串」之間),使用-d"" 您可以選擇要用作切割器的模式,使用-fNumber 您可以選擇要使用的部分拿。問題:「字串」將被刪除解決方案:
String=`echo "I am a useful and I am a string. Did I mention that I'm a string?" | cut -d "string" -f1`
String="$(String) string"
echo $String
它將刪除的分隔符號「字串」新增到使用輸出定義的 $String 變數的末尾
答案4
# 如何使用 POSIX sed 執行貪婪匹配:“test .*? string”
sed -e '
/test.*string/!d; # non-interesting line
/^test/s/string/&\
/; # append marker after the first substring "string"
/\n/{P;d;} # initial portion of pattern space is our result
s/test/\
&/;D; # remove portion before the substring "test"
' yourfile
其他POSIX-萊方法是從模式空間的末尾取出子字串“string”,一次1個,直到只剩下一個(在子字串“test”之後)。然後剩下的就是將子字串“test”放在前面:
sed -e '
:loop
s/\(test.*string\).*string.*/\1/
tloop
/^test/!s/test/\
&/;/\n/D
' yourfile