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

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

我经常在脚本中发现这种情况(而且,我必须承认,这是我自己写的):

a=$(echo "$x" | sed "s/foo/bar/")

或者

if echo "$x" | grep -q foo
then
    ...
fi

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

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

我就是找不到。有人找到吗?

答案1

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

  • 额外模式:?(pattern-list),,,,,,;*(pattern-list){n}(pattern-list){n,m}(pattern-list)@(pattern-list)!(pattern-list)
  • %P printf说明符将扩展正则表达式转换为模式(以及%R将扩展正则表达式转换为模式);
  • 測試expr == pattern中的狀況;[[ expr ]]
  • 参数${param/pattern/replacement}扩展。

狂欢

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

  • 它有自己的扩展模式和EXTENDED_GLOB选项;
  • -like 带有选项的扩展模式KSH_GLOB
  • expr == pattern(在测试中)的条件[[ expr ]]
  • 参数${pattern/pattern/replacement}扩展;
  • expr =~ extregexp测试中[[ expr ]]可以匹配扩展正则表达式的 条件,
    • 它可以使用聚合酶链反应如果设置了 RE_MATCH_PCRE 选项,则不使用普通的扩展正则表达式,
    • 带有括号的子表达式、MATCH参数和match参数(或BASH_REMATCH带有BASH_REMATCH选项集),sed可以进行样式替换;
  • zsh/pcre提供pcre_compile、、pcre_studypcre_match命令的模块以及-pcre-match 测试条件(在[[ expr ]]测试中);
  • 提供zsh/regex-regex-match 测试条件(在[[ expr ]]测试中)。

答案2

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

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

第一种形式只替换第一个实例。第二种形式是全局搜索和替换。

就你的情况而言,

代替:

if echo $x | grep foo
then
    ...
fi

考虑使用:

if [ $x =~ foo ]
then
    ...
fi

哪里foo是正则表达式。

答案3

测试变量是否包含模式的一种好的 posix 兼容方法是:

test ${var##*foo*} || <do something>;

语法参数扩展是:

 ${parameter##pattern}

其中pattern壳型

相关内容