Solaris 10 Bourne shell上的错误替换
我需要在字符串的最后一个选项之前提取部分字符串:Solaris 10 Bourne shell上的错误替换,shell,Shell,我需要在字符串的最后一个选项之前提取部分字符串: NDS=/opt/novell/opt/eDirectory/opt/abc 我只想要/opt/novell/opt/eDirectory/部分 我使用了NDSHOME=${NDS%opt*} 但我在Solaris 10上得到了糟糕的替代,即使用Bourne shell, 尽管此脚本在Linux和AIX上运行良好。 有人能找到解决方案吗?再次使用Bourne外壳。Solaris'/bin/sh不兼容Posix是出了名的 您可以使用sed NDS
NDS=/opt/novell/opt/eDirectory/opt/abc
我只想要/opt/novell/opt/eDirectory/
部分
我使用了NDSHOME=${NDS%opt*}
但我在Solaris 10上得到了糟糕的替代,即使用Bourne shell,
尽管此脚本在Linux和AIX上运行良好。
有人能找到解决方案吗?再次使用Bourne外壳。Solaris'/bin/sh不兼容Posix是出了名的 您可以使用
sed
NDSHOME=`echo "$NDS" | sed 's/^\(.*\)\<opt\>.*$/\1/'`
dirname
命令打印作为参数给定的路径名的最后一级以外的所有级别
$ NDS=/opt/novell/opt/eDirectory/opt/abc
$ NDSHOME=`dirname $NDS`
$ echo $NDSHOME
/opt/novell/opt/eDirectory/opt
(根据需要添加导出。)
编辑:
在这种情况下,上述方法不起作用。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
进入
试试这个:
NDSHOME=`echo "$NDS" | sed 's,\(.*\)/opt/.*$,\1,'`
(注意使用,
而不是/
作为分隔符,因此模式中的/
字符不必转义。)Solaris肯定与POSIX(以及一些相关标准,如xpg4和susv3)兼容,但它也非常重视与旧版本的兼容性
副作用是,当这两个特性以某种方式冲突时,默认情况下,受影响的命令与POSIX不兼容,因此不会破坏遗留脚本
如果您想要POSIX兼容性并且没有遗留脚本问题,只需按如下方式设置路径:
PATH=/usr/xpg6/bin:/usr/xpg4/bin:/usr/ccs/bin:$PATH
并将您的登录shell设置为/usr/xpg4/bin/sh
或者,如果不需要严格的遵从性,您可以使用/bin/ksh
作为默认shell
对于Solaris 10及更高版本,您不应该在新脚本中真正使用/bin/sh
作为参考,这里是Solaris 10手册页,Solaris 11手册页是。我们没有更改shell的选项,只能使用bourne shell。那么您就是SOL了。使用sed
或类似方法。他需要dirname
两次才能获得他想要的输出。在这种情况下,不确定opt之后是否只有一到两个级别。。它可以是任意数量的级别。因此,我们不能使用dirname。Solaris上的/bin/sh
命令是一个真正的(SystemV)Bourne Shell。你应该考虑使用KORN Shell(甚至BASH)。你应该写“Solaris/BIN/SH是臭名昭著的……”。Solaris本身绝对符合POSIX。@jlliagre足够公平,已更改。
NDSHOME=`echo "$NDS" | sed 's,\(.*\)/opt/.*$,\1,'`
PATH=/usr/xpg6/bin:/usr/xpg4/bin:/usr/ccs/bin:$PATH