执行“echo $x | sed ...”和“echo $x | grep ...”的更好方法

Dev*_*lar 14 shell grep sed

我经常在脚本中找到这个(而且,我不得不承认,我自己写的):

a=$(echo "$x" | sed "s/foo/bar/")
Run Code Online (Sandbox Code Playgroud)

或者

if echo "$x" | grep -q foo
then
    ...
fi
Run Code Online (Sandbox Code Playgroud)

考虑“foo”来包含一些正则表达式的东西。

我觉得应该有——而且很可能——一种更好的表达方式,一种不涉及两个命令和一个管道,而是将事物包装成一些更紧凑的表达方式。

我就是找不到。有人吗?

Chr*_*sen 12

除非你假设一个特定的 shell,否则没有比“管道回显到工具”更好的方法(或者只是一个“工具”本身,如expr);这是您真正可以依靠传统 Bourne shell和/或POSIX shell 的全部内容。如果您考虑其他外壳,那么还有其他一些内置可能性。

ksh

  • 额外的模式:?(pattern-list), *(pattern-list), {n}(pattern-list), {n,m}(pattern-list), @(pattern-list), !(pattern-list);
  • 所述%P 的printf说明符的扩展正则表达式转换成的图案(和%R用于扩展正则表达式到图案);
  • 测试中的expr == pattern条件[[ expr ]]
  • ${param/pattern/replacement}参数扩展。

bash

  • extglob启用ksh 的大多数额外模式的选项(no{n}{n,m});
  • expr == pattern条件(在[[ expr ]]测试);
  • ${param/pattern/replacement}参数扩展;
  • (在较新版本中)可以与扩展正则表达式匹配的expr =~ extregexp条件(在[[ expr ]]测试中)
    • 使用带括号的子表达式和BASH_REMATCH参数,可以完成sed样式的替换。

zsh

  • 它自己的扩展模式和EXTENDED_GLOB选项;
  • 带有KSH_GLOB选项的ksh类似扩展模式;
  • expr == pattern条件(在[[ expr ]]测试);
  • ${pattern/pattern/replacement}参数扩展;
  • 可以匹配扩展正则表达式的expr =~ extregexp条件(在[[ expr ]]测试中),
    • 如果设置了 RE_MATCH_PCRE 选项,它可以使用PCRE而不是普通的扩展正则表达式,
    • 用带括号的子表达式,所述MATCH参数和所述match参数(或BASH_REMATCH与该BASH_REMATCH选项集),sed的风格替换可以做;
  • zsh/pcre提供pcre_compilepcre_studypcre_match命令以及-pcre-match 测试条件的模块(在[[ expr ]]测试中);
  • zsh/regex提供-regex-match 测试条件的模块(在[[ expr ]]测试中)。


Dan*_*ath 6

要替换 sed 行,请执行以下操作

${a/foo/bar} 或者 ${a//foo/bar}

在第一种形式中,仅替换第一个实例。第二种形式是全局搜索和替换。

在你的情况下,这将是

代替:

if echo $x | grep foo
then
    ...
fi
Run Code Online (Sandbox Code Playgroud)

考虑使用:

if [ $x =~ foo ]
then
    ...
fi
Run Code Online (Sandbox Code Playgroud)

哪里foo是正则表达式。

  • 匹配运算符 `=~` 确实使用了正则表达式。这是真的,例如:`[[ "abcdddde" =~ ^a.*d+.g* ]]`(例如,这是零个或多个 g 而不是 g-wildcard)。 (3认同)