【问题标题】:What bash code implements the equivalent of left(), right() an mid() from BASIC?什么 bash 代码实现了 BASIC 中的 left()、right() 和 mid() 等价物?
【发布时间】:2012-10-03 06:24:51
【问题描述】:

我正在编写一些代码来测试通过groups username 的组成员资格,它返回类似vfclists : vfclists adm dialout cdrom plugdev lpadmin sambashare admin 的结果。

测试的代码是这样的

#!/bin/bash
UGROUP=$1
GROUP=$2
GROUPLIST=`groups $1`

echo $UGROUP
echo $GROUP
echo $GROUPLIST

if [[ "$GROUPLIST" == *"$GROUP"* ]]
then
  echo "$UGROUP is a member of $GROUP";
fi

问题是组的输出包含用户名。如何返回出现在用户名第二次出现右侧的输出部分?

如果不能保证用户名作为冒号后的第一组出现,是否有办法从输出中完全去除用户名?

【问题讨论】:

  • ...嗯,用户是真正的组 vfclistss..
  • 这是 sed 的工作。或者 awk,但我不那样摆动。

标签: bash substring


【解决方案1】:

对于bash4,您可以根据需要进行调整(使用关联数组):

declare -A arr

for i in $(groups); do arr[$i]=$i; done

user=root

if [[ ${arr[$user]} == $user ]]; then
    echo "$user exists"
fi

【讨论】:

    【解决方案2】:

    为什么不直接在groups 的输出中查找: 之后的匹配项?例如:

    #!/bin/bash
    
    SOME_USER="$1"
    SOME_GROUP="$2"
    
    if groups "$SOME_USER" | egrep ":.*\b$SOME_GROUP\b" > /dev/null
    then
        echo $SOME_USER is a member of $SOME_GROUP
    fi
    

    正则表达式matches a word boundary中的\b

    【讨论】:

    • 正则表达式中的 b 是什么意思?
    • @vfclists:它匹配一个单词边界 - 我已经更新了我的答案以链接到该文档。
    【解决方案3】:

    冒号后面的都是组名。可以有一个与用户同名的组(vfclists 就是这种情况)。要仅分隔冒号后的字符串,请删除冒号之前的所有内容:

    groups=$(groups $UGROUP)
    

    要从列表中删除给定的单词有点问题,因为如果它只是不同单词的子字符串,您不想将其删除。这应该有效:

    groups=$(groups $UGROUP)
    groups=${groups#*:}
    groups=${groups/ $UGROUP / } # Remove the word from the middle of the string
    groups=${groups% $UGROUP}    # Remove the word if it is the last one
    

    【讨论】:

      【解决方案4】:

      非常好的教程: https://linuxhandbook.com/bash-strings/

      关于这个问题的标题:

      如何在 Bash 中实现等价于 Basic 中的 left()、right() 和 mid()

      Extracting substrings标题处查看上述链接。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-16
        • 2019-06-09
        • 2013-09-11
        • 2014-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-29
        相关资源
        最近更新 更多