Bash 标准输出到变量。逐行使用mktmp、sed、grep等

Bash 标准输出到变量。逐行使用mktmp、sed、grep等,bash,ldap,sed,grep,Bash,Ldap,Sed,Grep,我使用ldapsearch从LDAP服务器获取一些用户。该命令的答复如下: uid: name.surname homeDirectory: /home/name sambaSID: S-1-4-32-224545876-87201423761-4821562975-6853 sambaHomeDrive: G: description: poI description: pPI sn: naut givenName: givenName: peter mail: mymail@example.

我使用ldapsearch从LDAP服务器获取一些用户。该命令的答复如下:

uid: name.surname
homeDirectory: /home/name
sambaSID: S-1-4-32-224545876-87201423761-4821562975-6853
sambaHomeDrive: G:
description: poI
description: pPI
sn: naut
givenName: givenName: peter
mail: mymail@example.com
现在,我想将“:”之后的每个字符串分配给一个变量(这两个描述可能会分配给一个数组?通过sambaSID,我只需要最后一个块(在本例中为6853[可能更长或更短])


任何帮助都将不胜感激。这里我尝试使用mktmp、sed、grep和许多丑陋的if语句。我没有其他想法…

我的贡献考虑了多个键(如描述)并附加了相应的值(由换行符分隔)

您可以在
ldapsearch
命令中使用
keys
作为
${keys[@]}
而不是
$OUTPUT

我更愿意使用关联数组,但直到bash 4.0才引入它们。因此,我使用数组作为键和值,并需要一个函数来检查键是否存在

...

keys=(uid homeDirectory sambaSID sambaHomeDrive description sn givenName mail)
declare -a values
i=0

...

index () {
    for ((x=0; x < ${#keys[@]}; x++)); do
        if [ "$1" == "${keys[$x]}" ]; then
            echo $x; return
        fi
    done
    echo -1
}

exec 5<> $LDIF
while read <&5 LINE
do
    key="${LINE%%:*}"
    value="${LINE#$key: }"
    x=`index $key`
    [ "$x" == -1 ] && x=$((i++)) || v="${values[$x]}"
    [ "$key" == "sambaSID" ] && value="${value##*-}"
    values[$x]="${v:+$v
}$value"
done

for ((x=0; x < ${#keys[@]}; x++)); do
    echo "${keys[$x]}: ${values[$x]}"
done

echo "Mail is ${values[`index 'mail'`]}."
。。。
keys=(uid homeditory sambaSID sambaHomeDrive description sn givenName mail)
声明-a值
i=0
...
索引(){
对于((x=0;x<${键[@]};x++),执行以下操作
如果[“$1”==“${keys[$x]}”];则
echo$x;返回
fi
完成
回声-1
}
执行官5$LDIF

而阅读我的贡献,它考虑多个键(如描述)并附加相应的值(以换行符分隔)

您可以在
ldapsearch
命令中使用
keys
作为
${keys[@]}
而不是
$OUTPUT

我更愿意使用关联数组,但直到bash 4.0才引入它们。因此,我使用数组作为键和值,并需要一个函数来检查键是否存在

...

keys=(uid homeDirectory sambaSID sambaHomeDrive description sn givenName mail)
declare -a values
i=0

...

index () {
    for ((x=0; x < ${#keys[@]}; x++)); do
        if [ "$1" == "${keys[$x]}" ]; then
            echo $x; return
        fi
    done
    echo -1
}

exec 5<> $LDIF
while read <&5 LINE
do
    key="${LINE%%:*}"
    value="${LINE#$key: }"
    x=`index $key`
    [ "$x" == -1 ] && x=$((i++)) || v="${values[$x]}"
    [ "$key" == "sambaSID" ] && value="${value##*-}"
    values[$x]="${v:+$v
}$value"
done

for ((x=0; x < ${#keys[@]}; x++)); do
    echo "${keys[$x]}: ${values[$x]}"
done

echo "Mail is ${values[`index 'mail'`]}."
。。。
keys=(uid homeditory sambaSID sambaHomeDrive description sn givenName mail)
声明-a值
i=0
...
索引(){
对于((x=0;x<${键[@]};x++),执行以下操作
如果[“$1”==“${keys[$x]}”];则
echo$x;返回
fi
完成
回声-1
}
执行官5$LDIF

同时阅读谢谢你的帮助。:)

andre-r的解决方案最适合它。但有一个问题。以下是脚本的输出:

script.sh:第29行:[:==:应为一元运算符 uid:uid=name.name,ou=Users,dc=smb,dc=chname.name 主目录: 桑巴西德:8426 sambaHomeDrive:G: 说明:p9o 序号:马修斯 吉文娜:名字 邮寄:myemail@example.com

因此uid不正确,sambaHomeDrive未解析。无法修复它:/


但真的非常感谢你的帮助!

谢谢你的帮助。:)

andre-r的解决方案最适合它。但有一个问题。以下是脚本的输出:

script.sh:第29行:[:==:应为一元运算符 uid:uid=name.name,ou=Users,dc=smb,dc=chname.name 主目录: 桑巴西德:8426 sambaHomeDrive:G: 说明:p9o 序号:马修斯 吉文娜:名字 邮寄:myemail@example.com

因此uid不正确,sambaHomeDrive未解析。无法修复它:/


但真的非常感谢您的帮助!

如果您真的不在乎重复的键,并且假设第一个“:”左边的所有内容都是字母数字,右边的任何内容都不包含单引号,则可以执行以下操作:

while read line; do eval $(echo "$line" | sed 's/^\([^:]\+\):[ ]\+\(.*\)/\1='"'"'\2'"'/") done echo "uid is $uid, home directory is $homeDirectory." 边读边做 eval$(echo“$line”| sed's/^\([^::\+\):[]\+\(.*\)/\1='''''''''\2''/')) 完成 echo“uid是$uid,主目录是$homeditory。”
如果您真的需要保留重复的密钥,那么修改它以支持它并不难。当然,“eval”可能是危险的,正如已经指出的,但是如果上述假设成立(在“:”右侧没有单引号),这种使用是安全的。

如果您并不真正关心重复的键,并且假设第一个“:”左边的所有内容都是字母数字,右边的任何内容都不包含单引号,则可以执行以下操作:

while read line; do eval $(echo "$line" | sed 's/^\([^:]\+\):[ ]\+\(.*\)/\1='"'"'\2'"'/") done echo "uid is $uid, home directory is $homeDirectory." 边读边做 eval$(echo“$line”| sed's/^\([^::\+\):[]\+\(.*\)/\1='''''''''\2''/')) 完成 echo“uid是$uid,主目录是$homeditory。”
如果您真的需要保留重复的密钥,那么修改它以支持它就不难了。当然,“eval”可能很危险,正如前面所指出的,但是如果上述假设成立(在“:”右侧没有单引号),这种用法是安全的。

这比使用bash简单得多,您可能会使用bash


#!/bin/bash
while read line ; do
        n="${line%%:*}"
        v="${line#*: }"
        eval $n=\"$v\"
done
sambaSID=${sambaSID/*-/}

$ ldapsearch | this_script.sh

在这一点上,所有的需求都得到了满足,并且您有以每个ldiff属性命名的局部变量。这并不是一个好主意。

如果您有bash,那么它要简单得多,您可能会这样做


#!/bin/bash
while read line ; do
        n="${line%%:*}"
        v="${line#*: }"
        eval $n=\"$v\"
done
sambaSID=${sambaSID/*-/}

$ ldapsearch | this_script.sh

此时,所有要求都得到满足,并且您有以每个ldiff属性命名的局部变量。这不是一个好主意。

对不起,我的错。我更新了答案。将变量括在“”中始终是一个好主意。不起作用。但非常感谢您的帮助:)uid是uid=name.nname,ou=Users,dc=aksa,dc=chname.nname.Mail是mymail@example.com.homeDirectory是。我在上面的行中使用了您的代码1:1。无法访问代码atm。对不起。但我用dz代码的编辑版本解决了我的问题。谢谢。对不起,我的错。我更新了答案。它是我的将变量括在“”中总是一个好主意。不起作用。但非常感谢您的帮助:)uid是uid=name.nname,ou=Users,dc=aksa,dc=chname.nname.Mail是mymail@example.com.homeDirectory是。我在上面的行中使用了您的代码1:1。无法访问代码atm。抱歉。但我用dz代码的编辑版本解决了我的问题。谢谢