【问题标题】:Check for duplicate word in comma-separated string in bash检查bash中逗号分隔字符串中的重复单词
【发布时间】:2019-12-12 13:08:04
【问题描述】:

我需要检查一个变量不包含逗号分隔字符串中的重复条目。

例如,在$animals 内部,如果我有:

,dog,cat,bird,goat,fish,

这将被认为是有效的,因为每个单词都是唯一的。

字符串:

,dog,cat,dog,bird,fish,

将无效,因为dog 输入了两次。

,dog,cat,dogs,bird,fish,

有效,因为只有一个 dog 实例(dogs 存在但允许,因为它不是同一个确切的词)

字符串:

,dog,cat,DOG,bird,fish

同样无效,因为 dogDOG 相同,只是大写。

有什么办法可以做到吗?我会放一些我试过的代码,但我什至不知道用什么来做实验。

在 10.11.6 El Capitan 上使用 bash 3.2.57(1)-release

【问题讨论】:

    标签: bash macos if-statement command-line comma


    【解决方案1】:

    区分大小写:

    echo ",dog,cat,dog,bird,fish," | tr ',' '\n' | grep -v '^$' | sort | uniq -c | sort -k 1,1nr
    

    不区分大小写

    echo ",dog,DOG,cat,dog,bird,fish," | tr ',' '\n' | grep -v '^$' | sort -rf | uniq -ci | sort -k 1,1nr
    

    执行反向排序 (-r) 并不区分大小写以在大写字母之后获取小写字母。然后uniq 他们和-i。 (您可能必须确保定义的排序规则 LC_COLLATE 以及 LANGLC_ALL 等语言环境不会影响 sort 的行为。

    然后检查第一行的数字是否> 1

    【讨论】:

    • Then check if the number in the first row > 1 可以使用简单的awk 脚本来完成,例如awk '{ if ($1 > 1) print "Contains duplicates"; }' 可能使用head -n1。甚至可以| grep -v ' *1 ' | wc -l 并将计数与零进行比较。
    • 谢谢,这也很好用!我可以看到这在需要计算重复项并将它们列出的应用程序中也很有用。
    • 此外,如果您的uniq 版本在字符串的开头添加了空格,那么将其通过管道传送到sed 's/^[\ ]*//' 将删除这些空格。
    • 检查区分大小写的重复项也可以使用以下 if 语句实现:if echo ",dog,cat,dog,bird,fish," | tr ',' '\n' | grep -v '^$' | sort | uniq -c | sort -k 1,1nr | sed 's/^[\ ]*//' | grep -vq '^1\ '; then echo "Contains duplicates"; else echo "Contains no duplicates";fi
    【解决方案2】:

    简单的基于脚本的解决方案

    用法

    $ .\script.sh ,dog,dog,cat,
    

    实际脚本

    #!/bin/sh
    
    num_duplicated() {
        echo $1 |
        tr ',' '\n' | # Split each items into its own line
        tr '[:upper:]' '[:lower:]' | # Convert everything to lowercase
        sort | # Sorts the lines (required for the call to `uniq`
        uniq -d | # Passing the `-d` flag to show only duplicated lines
        grep -v '^$' | # Passing `-v` on the pattern `^$` to remove empty lines
        wc -l # Count the number of duplicate lines
    }
    
    main() {
        num_duplicates=$(num_duplicated "$1") 
        if [[ $num_duplicates -eq '0' ]]
        then
            echo "No duplicates"
        else
            echo "Contains duplicate(s)"
        fi
    }
    
    main $1
    

    【讨论】:

    • @KamilCuk 很好地抓住了wc -l | # Count...,我正在整理 Stack Overflow 编辑器,没有仔细检查。关于你的第二点,我想也许我们会让 OP 澄清他/她所说的... Would also be invalid since dog is not the same as DOG.
    • 这对我来说效果很好,谢谢!也像 cmets 中每个命令的细分。关于“无效,因为狗与狗不同”我犯了一个错误。我不是以英语为母语的人,我有一个朋友为我翻译德语/英语。我编辑了问题以解决问题。
    • 另外,tr '[:upper:]' '[:lower:'] 不需要是tr '[:upper:]' '[:lower:]' 吗?我在您的问题中更改了它,但如果我不正确,请随时将其更改回来。
    猜你喜欢
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 2013-01-08
    • 2019-01-23
    • 1970-01-01
    • 2012-08-12
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多