Linux和Solaris的grep通用方法

时间:2016-09-06 19:04:59

标签: linux bash solaris

我目前正在评估相对较长的脚本集合,并对源代码进行更改,以便在Linux和SunOS框中执行相同的脚本集。部分代码有一个简单的grep:

#Linux
echo -e  "\n foo \n bar \n test ok" | grep -Evw 'foo|bar'

如果翻译为:

,我的移植尝试工作正常
#SunOS
echo -e  "\n foo \n bar \n test ok" | /usr/xpg4/bin/grep -Ev 'foo|bar'

有没有办法在Bash中编写单个语句才能在两种情况下都能工作?或者,我是否应该做好心理准备,为每个操作系统开始实现额外的if / else语句?

在这种情况下,似乎/ bin / grep可以同时执行正则表达式和单词匹配,但是使用/ usr / bin / grep我们只能执行单词而不是两者:

$ echo -e  "\n foo \n bar \n test ok" | grep -Evw 'foo|bar'
grep: illegal option -- E
Usage: grep [-c|-l|-q] -bhinsvw pattern file . . .
$ echo -e  "\n foo \n bar \n test ok" | /usr/xpg4/bin/grep -Evw 'foo|bar'
Usage:  grep [-c|-l|-q] [-bhinsvwx] pattern_list [file ...]
    grep [-c|-l|-q] [-bhinsvwx] [-e pattern_list]... [-f pattern_file]... [file...]
    grep -E [-c|-l|-q] [-bhinsvx] pattern_list [file ...]
    grep -E [-c|-l|-q] [-bhinsvx] [-e pattern_list]... [-f pattern_file]... [file...]
    grep -F [-c|-l|-q] [-bhinsvx] pattern_list [file ...]
    grep -F [-c|-l|-q] [-bhinsvx] [-e pattern_list]... [-f pattern_file]... [file...]

3 个答案:

答案 0 :(得分:3)

如何将类似的内容放在脚本的顶部:

[ -d /usr/xpg4/bin ] && PATH="/usr/xpg4/bin:$PATH"

然后以下行将适用于两个系统:

echo -e  "\n foo \n bar \n test ok" | grep -Evw 'foo|bar'

当然,我们的想法是检查目录/usr/xpg4/bin是否存在,如果存在,我们可以假设它包含一个支持我们想要的选项的grep(可能是GNU {{1} }})。所以只需在grep的开头添加该目录,以便它具有最高优先级。

答案 1 :(得分:3)

  

有没有办法在Bash中编写单个语句才能在两种情况下都有效?

  

或者,我是否应该做好心理准备,为每个操作系统开始实现额外的if / else语句?

不,如果可能,应该避免这种情况。在您的情况下,可以使用标准命令完成所有操作,因此无需添加特定于操作系统的代码。

这是一种可移植的方式。这应该适用于所有类似Unix的机器:

sigmoid

PATH=`getconf PATH`:$PATH # Should be done once at the beginning of scripts. printf "\n foo \n bar \n test ok" | grep -Ev '\<foo\>|\<bar>\' 在所有Unix / Unix类实现上返回PATH到POSIX兼容命令。

当需要格式化命令时,应使用

getconf PATHprintf无法可靠地使用,因为其行为未定义,即使在POSIX下也是如此。

echo是使用扩展正则表达式指定单词边界的POSIX方法。

请注意,我没有使用\<...\>,而是使用较旧的$(getconf PATH)语法,因为在Solaris 10上,您可能正在运行旧版Bourne shell。

答案 2 :(得分:0)

一个解决方案是放在 shebang 之后:

grep_path=/usr/lib/gnu/bin # <- EDIT ME
PATH=$grep_path:$PATH

# will work on any platform with a GNU grep
grep foobar file