我需要在字符串中的最后选择之前提取字符串的一部分:获取坏替代在Solaris 10上的Bourne shell
NDS=/opt/novell/opt/eDirectory/opt/abc
我只想要/opt/novell/opt/eDirectory/
部分
我以前NDSHOME=${NDS%opt*}
但我在Solaris 10上使用Bourne shell, 进行错误替换,尽管此脚本在Linux和AIX上运行良好。 有人可以找到解决办法吗?
我需要在字符串中的最后选择之前提取字符串的一部分:获取坏替代在Solaris 10上的Bourne shell
NDS=/opt/novell/opt/eDirectory/opt/abc
我只想要/opt/novell/opt/eDirectory/
部分
我以前NDSHOME=${NDS%opt*}
但我在Solaris 10上使用Bourne shell, 进行错误替换,尽管此脚本在Linux和AIX上运行良好。 有人可以找到解决办法吗?
Solaris'/ bin/sh是臭名昭着的不Posix兼容。
你可以尝试以下解决方法与sed
NDSHOME=`echo "$NDS" | sed 's/^\(.*\)\<opt\>.*$/\1/'`
注:通常我会用$()
代替backtics的命令替换的,但我不认为在Solaris上的工作要么。
编辑 改变它,以便opt
不匹配字内边界
$ echo $NDS
/opt/novell/opt/eDirectory/opt/helicopter
$ echo "$NDS" | sed 's/^\(.*\)\<opt\>.*$/\1/'
/opt/novell/opt/eDirectory/
改为使用Bourne-Again shell。
我们没有更改shell的选项,我们只能使用bourne shell。 – gold 2012-01-02 06:16:46
然后你就是SOL。改为使用'sed'或类似的东西。 – 2012-01-02 06:17:12
的dirname
命令打印所有,但作为参数给出的路径名的最后一个级别。
$ NDS=/opt/novell/opt/eDirectory/opt/abc
$ NDSHOME=`dirname $NDS`
$ echo $NDSHOME
/opt/novell/opt/eDirectory/opt
(根据需要添加export
)
编辑:
以上在这种情况下无法正常工作。 OP想要删除最后一个opt
之后的路径的所有组件,而不仅仅是最后一个组件。如果它对别人有用,我会把它留在这里。
您可能使用dirname
在一个循环中,停车时最后一个组件(由basename
确定)是'选择':
NDSHOME="$NDS"
while [ "`basename $NDSHOME`" != opt ] ; do
NDSHOME="`dirname $NDSHOME`"
done
但是这是比它需要更加复杂; sed是一个更好的解决方案。
SiegeX的答案很好,但它将opt
当作一个字符串,而不仅仅是一个路径组件。例如,它会变成
/opt/novell/opt/eDirectory/opt/helicopter
到
/opt/novell/opt/eDirectory/opt/helic
试试这个:
NDSHOME=`echo "$NDS" | sed 's,\(.*\)/opt/.*$,\1,'`
(注意用,
而非/
作为分隔符,所以在该/
字符模式不一定要逃脱。)
Solaris绝对符合POSIX(以及xpg4和susv3等几个相关标准),但它也非常重视兼容旧版本。
副作用是,当这两个功能在某些方面发生冲突时,默认情况下,受影响的命令不符合POSIX,不会破坏旧版脚本。
如果您想POSIX兼容,没有旧式脚本问题,只是设置PATH这样的:
PATH=/usr/xpg6/bin:/usr/xpg4/bin:/usr/ccs/bin:$PATH
和你的登录shell设置为/usr/xpg4/bin/sh
或者,如果你并不需要严格遵守,您可能只需使用/bin/ksh
作为默认外壳。
对于Solaris 10及更早版本,在新脚本中根本不应该使用/bin/sh
。
谢谢这真的很有用 – gold 2012-01-03 05:26:31
Solaris上的'/ bin/sh'命令是一个真正的(System V)Bourne Shell。你应该考虑使用Korn Shell(或者甚至是Bash)。 – 2012-01-02 07:37:39