变量上的 grep

gkm*_*hit 99 shell grep string

假设我有一个变量

line="This is where we select from a table."
Run Code Online (Sandbox Code Playgroud)

现在我想 grep 有多少次 select 在句子中出现。

grep -ci "select" $line
Run Code Online (Sandbox Code Playgroud)

我试过了,但没有用。我也试过

grep -ci "select" "$line"
Run Code Online (Sandbox Code Playgroud)

它仍然不起作用。我收到以下错误。

grep: This is where we select from a table.: No such file or directory
Run Code Online (Sandbox Code Playgroud)

Joh*_*ith 138

grep阅读其标准输入。你去,使用管道......

$ echo "$line" | grep select
Run Code Online (Sandbox Code Playgroud)

... 或这里的字符串...

$ grep select <<< "$line"
Run Code Online (Sandbox Code Playgroud)

此外,您可能希望在 grepping 之前用换行符替换空格:

$ echo "$line" | tr ' ' '\n' | grep select
Run Code Online (Sandbox Code Playgroud)

...或者您可以要求grep仅打印匹配项:

$ echo "$line" | grep -o select
Run Code Online (Sandbox Code Playgroud)

这将允许您在匹配时摆脱该行的其余部分。

编辑:哎呀,读得太快了,谢谢马可。为了计算出现次数,只需将其中任何一个通过管道传输到wc(1);)

lzkata的评论之后进行的另一个编辑,$line在使用echo.

  • 由于 OP 想要计算字符串出现的次数,您可以添加一个 `wc` 来完成任务:`grep -o &lt;string&gt; &lt;&lt;&lt; "$variable" | wc -l` (3认同)
  • 使用 `echo "$line"` 保留现有的换行符,而不是使用 `tr` 创建换行符 (2认同)

mik*_*erv 7

test=$line i=0
while case "$test" in (*select*)
test=${test#*select};;(*) ! :;;
esac; do i=$(($i+1)); done
Run Code Online (Sandbox Code Playgroud)

你不需要调用grep这么简单的东西。

或者作为一个函数:

occur() while case "$1" in (*"$2"*) set -- \
        "${1#*"$2"}" "$2" "${3:-0}" "$((${4:-0}+1))";;
        (*) return "$((${4:-0}<${3:-1}))";;esac
        do : "${_occur:+$((_occur=$4))}";done
Run Code Online (Sandbox Code Playgroud)

它需要 2 或 3 个参数。提供任何更多内容都会扭曲其结果。你可以像这样使用它:

_occur=0; occur ... . 2 && echo "count: $_occur"
Run Code Online (Sandbox Code Playgroud)

...如果它至少出现 2 次,它会打印.in 的...出现次数。像这样:

count: 3
Run Code Online (Sandbox Code Playgroud)

如果$_occur为空或unset当它被调用时,则它根本不会影响任何 shell 变量,return如果"$2"发生的"$1"次数少于1,则为 1 "$3"。或者,如果仅使用两个 args 调用,则return只有"$2"不在"$1". 否则返回0。

因此,以最简单的形式,您可以执行以下操作:

occur '' . && echo yay || echo shite
Run Code Online (Sandbox Code Playgroud)

...打印...

shite
Run Code Online (Sandbox Code Playgroud)

...但...

occur . . && echo yay || echo shite
Run Code Online (Sandbox Code Playgroud)

...将打印...

yay
Run Code Online (Sandbox Code Playgroud)

你也可能会有所不同写了一点,周围省略了引号$2中都(*"$2"*)"${1#*"$2"}"声明。如果你这样做,那么你可以使用 shell globs 进行匹配,例如sh[io]te匹配测试。