我需要在字符串中的最后一个opt之前提取部分字符串:
NDS=/opt/novell/opt/eDirectory/opt/abc
我只想要/opt/novell/opt/eDirectory/
部分
我使用了NDSHOME=${NDS%opt*}
但我在Solaris 10上使用Bourne shell进行了错误的替换,
虽然这个脚本在Linux和AIX上运行良好。
有人可以找到解决方案??
答案 0 :(得分:1)
dirname
命令打印除了作为参数给出的路径名的最后一级以外的所有级别。
$ NDS=/opt/novell/opt/eDirectory/opt/abc
$ NDSHOME=`dirname $NDS`
$ echo $NDSHOME
/opt/novell/opt/eDirectory/opt
(根据需要添加export
。)
编辑:
以上在这种情况下不起作用。 OP希望删除最后opt
之后的路径的所有组件,而不仅仅是最后一个组件。我会留在这里,以防它对其他人有用。
你可以在循环中使用dirname
,当最后一个组件(由basename
确定)是'opt'时停止:
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,'`
(请注意,使用,
而不是/
作为分隔符,因此模式中的/
字符不必转义。)
答案 1 :(得分: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
作为默认shell。
对于Solaris 10及更早版本,您不应该在新脚本中使用/bin/sh
。
答案 2 :(得分:0)
改为使用Bourne-Again shell。
答案 3 :(得分:0)
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/