【问题标题】:bash remove duplicate string from list [duplicate]bash从列表中删除重复的字符串[重复]
【发布时间】:2016-10-24 00:51:27
【问题描述】:

我想从字符串中删除重复的字符串。示例:

A="Dog Cat Horse Dog Dog Cat"

字符串 A 应该如下所示:

A="Dog Cat Horse"

我怎样才能为此编写一个 Shell 脚本?

【问题讨论】:

  • @heemayl:您声称重复的问题是关于排序和删除重复项。这里的问题不是关于排序,只是关于删除重复…
  • @anubhava:您声称重复的问题是关于排序和删除重复项。这里的问题不是关于排序,只是关于删除重复…

标签: string bash grep


【解决方案1】:

如果顺序不重要,可以使用关联数组:

declare -A uniq
for k in $A ; do uniq[$k]=1 ; done
echo ${!uniq[@]}

【讨论】:

  • 在关联数组的情况下,是否有特定的键/索引列出顺序?
  • 请注意,如果原始字符串包含全局字符,这可能会失败。可以用set -f“修复”。
【解决方案2】:

你可以用这个,

echo "a a b b c c" | tr ' ' '\n' | sort | uniq | tr '\n' ' ' | sed -e 's/[[:space:]]*$//'

【讨论】:

  • 这会颠倒顺序。
【解决方案3】:
  1. (安全地)将字符串拆分为空格,为每个单词创建一个数组:

    read -r -d '' -a words < <(printf '%s\0' "$A")
    
  2. 循环数组的字段,将单词存储到关联数组中;如果该词已被看到,则忽略它

    declare -A Aseen
    Aunique=()
    for w in "${words[@]}"; do
        [[ ${Aseen[$w]} ]] && continue
        Aunique+=( "$w" )
        Aseen[$w]=x
    done
    
  3. 您可以将Aunique 数组打印到标准输出:

    printf '%s\n' "${Aunique[@]}"
    

    产生:

    Dog
    Cat
    Horse
    

    或用它创建一个新字符串

    Anew="${Aunique[*]}"
    printf '%s\n' "$Anew"
    

    产生:

    Dog Cat Horse
    

    或使用分隔符加入数组,例如,使用字符 ,:

    IFS=, eval 'Asep="${Aunique[*]}"'
    printf '%s\n' "${Asep[@]}"
    

    产生:

    Dog,Cat,Horse
    

所有这些都使用 Bash≥4 特性。如果您卡在较旧的 Bash 版本上,有一些变通方法,但它不会那么安全、美观和简单……

注意。此方法不会对字符串进行排序:单词保持原来的顺序,只有重复的被删除。


这是在空格字符上分割字符串的规范(并且安全!)方法(或者,更一般地在特殊变量IFS中包含的字符上,它具有默认值空格-制表符-换行符)。不要使用像words=( $A ) 这样的恐怖:它会受到文件名扩展(通配符)的影响。另一种广泛遇到的方法是read -r -a words &lt;&lt;&lt; "$A";这很好(即安全),但不会处理 A 中的换行符。

这里使用eval是100%安全的(因为单引号);这实际上是在 Bash 中加入数组元素(或在 POSIX shell 中加入位置参数)的规范方法。

【讨论】:

  • 在关联数组的情况下,是否有特定的键/索引列出顺序?
  • @anishane:顺序由散列密钥(一种模糊的加密顺序)控制。但是在这个答案的情况下,关联数组仅用于记住已经遇到的单词,而不是构建最终的字符串(单词在Aunique中出现的顺序是原始字符串的顺序)。
  • 是的,明白了...只是想知道,如果代码中的顺序很容易预测。然后我们可以使用更简单的机制,类似于@choroba 的答案......
【解决方案4】:

呆呆的:

 awk -v RS="[ \n]" -v ORS=" " '!($0 in a){print;a[$0]}' <(echo $A)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-02
    • 2011-12-17
    • 1970-01-01
    • 2019-05-05
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 2014-09-16
    相关资源
    最近更新 更多