Bash 字符串操作 with/without 空格

Bash string manipulation with/without whitespaces

考虑在 bash 中设置一个包含项目列表的字符串:

# BLUBB="item foobar blubb bar"

进一步考虑有一个项目排除列表:

# EXCLUDE="item bar blubb"

将此问题解决为包含 BLUBB w/o EXCLUDE 的列表的最简单方法是什么。我的第一个方法是:

# for i in $EXCLUDE; do BLUBB=${BLUBB//$i/}; done

但这另外从 foobar 中删除了 bar。所以看起来,必须在 $i 之前和之后寻找空白或什么都没有。这个的语法如何?

可以这样做:

#/bin/bash
BLUBB="item foobar blubb bar"
EXCLUDE="item bar blubb"
for word in ${BLUBB} ${EXCLUDE} ${EXCLUDE}; do
    echo ${word}
done | sort | uniq -u

我会在 bash 中使用关联数组执行此操作:

$ BLUBB="item foobar blubb bar"
$ EXCLUDE="item bar blubb"
$ declare -A h
$ for word in $BLUBB; do h[$word]=1; done
$ declare -p h
declare -A h='([blubb]="1" [bar]="1" [foobar]="1" [item]="1" )'
$ for word in $EXCLUDE; do unset "h[$word]"; done
$ declare -p h
declare -A h='([foobar]="1" )'
$ words="${!h[*]}"
$ echo "$words"
foobar

如果 BLUBB 或 EXCLUDE 中的任何 "words" 包含空格,则必须使用索引数组来保存它们:

$ BLUBB=(item foobar blubb bar "word with spaces")
$ EXCLUDE=(item bar blubb with)
$ declare -A h
$ for elem in "${BLUBB[@]}"; do h["$elem"]=1; done
$ for elem in "${EXCLUDE[@]}"; do unset "h[$elem]"; done
$ declare -p h
declare -A h='(["word with spaces"]="1" [foobar]="1" )'