
在bash
腳本中,如何從字串中刪除單字,該單字將儲存在變數中。
FOO="CATS DOGS FISH MICE"
WORDTOREMOVE="MICE"
答案1
使用bash
子字串替換(從 ksh93 複製):
FOO=${FOO//"$WORDTOREMOVE"/}
將//
所有出現的子字串 () 替換為和$WORDTOREMOVE
之間的內容。在這種情況下什麼都沒有。/
}
請注意周圍的引號,$WORDTOREMOVE
以確保內容被視為固定字串而不是模式。
當替換為空時,/
也可以省略:${FOO//"$WORDTOREMOVE"}
。
有關在 bash 中使用字串的方法和其他方法的信息,請參閱 部分10.1.操作字串的進階 Bash 腳本指南。
答案2
嘗試:
$ printf '%s\n' "${FOO//"$WORDTOREMOVE"/}"
CATS DOGS FISH
這也適用於ksh93
(它來自哪裡)mksh
和zsh
。
正面:
FOO="CATS DOGS FISH MICE"
WORDTOREMOVE="MICE"
remove_word() (
set -f
IFS=' '
s=$1
w=$2
set -- $1
for arg do
shift
[ "$arg" = "$w" ] && continue
set -- "$@" "$arg"
done
printf '%s\n' "$*"
)
remove_word "$FOO" "$WORDTOREMOVE"
它假設您的單字是用空格分隔的,並且具有刪除前後空格的副作用"$WORDTOREMOVE"
。
答案3
您可以使用sed
像這樣:
echo $FOO | sed s/"$WORDTOREMOVE"//
答案4
刪除一個單字從表示以空格分隔的單字清單的字串中獲取資料並不那麼容易,因為您需要決定如何處理每一側的空格。
即使在單字之間始終有一個空格的馴服表示中,您也需要區分幾種不同的情況:
- 中間的單字:
foo MICE bar
->foo bar
:單字及其之前的空格和之後的空格替換為單一空格。${var/+( )MICE+( )/ }
- 開頭的單字:
MICE foo bar
->foo bar
:單字和後面的空格替換為空:${var/MICE+( )}
- 末尾的單字:
foo bar MICE
->foo bar
:單字和前面的空格替換為空:${var/+( )MICE}
。 - 然後會出現多次連續出現單字 where 的問題,因為第一個替換會佔用第二個 MICE 之前的空間,因此
${var// MICE / }
無法正常運作。foo MICE MICE bar
(上面使用${var/pattern/replacement}
ksh93 中的運算子)。
不過,如果您在進行替換之前在開頭和結尾添加一個空格並在之後刪除它們,那麼它會變得更容易,因為這樣您就可以用一個替換運算符覆蓋所有基礎:
var='MICE foo MICE MICE bar MICE'
word=MICE
var=" $var "
var=${var//+(+([[:space:]])"$word")+([[:space:]])/ }
var=${var# } var=${var% }
您需要事先shopt -s extglob
在 bash 或set -o kshglob
zsh 中支援+([[:space:]])
ksh88 運算子來符合 1 個或多個空白字元。
或使用zsh
's 自己的extendedglob
s ( set -o extendedglob
),其中 ksh+(x)
變成x##
:
var=${var//([[:space:]]##$word)##[[:space:]]##/ }
甚至可以恢復單字 with 之前或之後的間距(在zsh
; ksh93 中會有等效的內容,而不是 bash):
var='MICE foo MICE MICE bar MICE'
word=MICE
set -o extendedglob
var=" $var "
var=${var//(#b)([[:space:]]##$word)##([[:space:]]##)/$match[2]}
var=${var# } var=${var% }
如果您有一個實際的變量,而不是包含列表表示的標量變量清單(數組)變量,如:
var=(MICE foo MICE MICE bar MICE)
然後問題就簡化為從陣列中刪除特定元素,這對於具有適當數組變數的 shell 來說變得微不足道,例如zsh
(該var=(foo bar)
語法的來源):
var=( ${var:#$word} )