Better way to do "echo $x | sed ..." and "echo $x | grep ..."
Unless you assume a specific shell, there is no better way to do this than “pipe echo to tool” (or just a “tool” itself like expr); it is all you can really count on with the traditional Bourne shell and/or the POSIX shell. If you consider other shells, then there are some other built-in possibilities.
ksh has
- extra patterns:
?(pattern-list)
,*(pattern-list)
,{n}(pattern-list)
,{n,m}(pattern-list)
,@(pattern-list)
,!(pattern-list)
; - the
%P
printf specifier to convert a extended regular expression into a pattern (and%R
for extended regular expression to pattern); - the
expr == pattern
condition in[[ expr ]]
tests; - the
${param/pattern/replacement}
parameter expansion.
bash has
- the
extglob
option to enable most of the extra patterns of ksh (no{n}
and{n,m}
); - the
expr == pattern
condition (in[[ expr ]]
tests); - the
${param/pattern/replacement}
parameter expansion; - (in newer versions) the
expr =~ extregexp
condition (in[[ expr ]]
tests) that can match against extended regular expressions- with parenthesized subexpressions and the
BASH_REMATCH
parameter, sed-style replacements could be done.
- with parenthesized subexpressions and the
zsh has
- its own extended patterns with the
EXTENDED_GLOB
option; -
ksh-like extended patterns with the
KSH_GLOB
option; - the
expr == pattern
condition (in[[ expr ]]
tests); - the
${pattern/pattern/replacement}
parameter expansion; - the
expr =~ extregexp
condition (in[[ expr ]]
tests) that can match against extended regular expressions,- it can use PCRE instead of plain extended regular expressions if the RE_MATCH_PCRE option is set,
- with parenthesized subexpressions, the
MATCH
parameter, and thematch
parameter (orBASH_REMATCH
with theBASH_REMATCH
option set), sed-style replacements could be done;
- the
zsh/pcre
module that offerspcre_compile
,pcre_study
, andpcre_match
commands and the-pcre-match
test condition (in[[ expr ]]
tests); - the
zsh/regex
module that offers the-regex-match
test condition (in[[ expr ]]
tests).
To replace the sed line, do something like
${a/foo/bar}
or ${a//foo/bar}
In the first form, only the first instance is replaced. The second form is a global search & replace.
In your case, it would be
Instead of:
if echo $x | grep foo
then
...
fi
Consider using:
if [ $x =~ foo ]
then
...
fi
Where foo
is a regular expression.
A good posix compatible way for testing if a variable contains a pattern is:
test ${var##*foo*} || <do something>;
The syntax of the parameter expansion is:
${parameter##pattern}
where pattern
is a shell pattern.