如何从Bash脚本中的字符串中删除重复的单词?

时间:2015-05-18 04:02:38

标签: bash

我有一个包含重复单词的字符串,例如:

abc, def, abc, def

如何删除重复项?我需要的字符串是:

abc, def

4 个答案:

答案 0 :(得分:6)

我们有这个测试文件:

$ cat file
abc, def, abc, def

删除重复的字词:

$ sed -r ':a; s/\b([[:alnum:]]+)\b(.*)\b\1\b/\1\2/g; ta; s/(, )+/, /g; s/, *$//' file
abc, def

如何运作

  • :a

    这定义了标签a

  • s/\b([[:alnum:]]+)\b(.*)\b\1\b/\1\2/g

    这会查找由字母数字字符组成的重复单词,并删除第二次出现的内容。

  • ta

    如果最后一个替换命令导致更改,则会跳回标签a以重试。

    通过这种方式,代码一直在寻找重复项,直到没有剩余。

  • s/(, )+/, /g; s/, *$//

    这两个替换命令可以清除剩余的逗号空间组合。

Mac OSX或其他BSD系统

对于Mac OSX或其他BSD系统,请尝试:

sed -E -e ':a' -e 's/\b([[:alnum:]]+)\b(.*)\b\1\b/\1\2/g' -e 'ta' -e 's/(, )+/, /g' -e 's/, *$//' file

使用字符串而不是文件

sed可以轻松处理来自文件的输入,如上所示,或者来自shell字符串,如下所示:

$ echo 'ab, cd, cd, ab, ef' | sed -r ':a; s/\b([[:alnum:]]+)\b(.*)\b\1\b/\1\2/g; ta; s/(, )+/, /g; s/, *$//'
ab, cd, ef

答案 1 :(得分:3)

您可以使用awk执行此操作。

示例:

#!/bin/bash
string="abc, def, abc, def"
string=$(printf '%s\n' "$string" | awk -v RS='[,[:space:]]+' '!a[$0]++{printf "%s%s", $0, RT}')
string="${string%,*}"
echo "$string"

输出:

abc, def

答案 2 :(得分:2)

这也可以在纯Bash中完成:

#!/bin/bash

string="abc, def, abc, def"

declare -A words

IFS=", "
for w in $string; do
  words+=( [$w]="" )
done

echo ${!words[@]}

<强>输出

def abc

<强>解释

words是一个关联数组(declare -A words),每个单词都被添加为 一把钥匙:

words+=( [${w}]="" )

(我们不需要它的值,因此我将""作为值。)

唯一字词列表是键列表(${!words[@]})。

有一点需要注意,输出不是由", "分隔的。 (你会 必须再次迭代。 IFS仅与${words[*]}一起使用,甚至仅与IFS一起使用 使用Dim strCurrency As String = "" strCurrency = "SGD" .Cells(cRow, 17).NumberFormat = """"+strCurrency +"""#,##0.00_);("""+strCurrency +"""#,##0.00)" 的第一个字符。)

答案 3 :(得分:1)

对于这种情况,我有另一种方式。我更改了输入字符串,例如下面的命令并运行命令来编辑它:

#string="abc def abc def"
$ echo "abc def abc def" | xargs -n1 | sort -u | xargs |  sed "s# #, #g"
abc, def

感谢所有支持!