grep在变量上


58

假设我有一个变量

line="This is where we select from a table."

现在我想重复一下句子中选择的次数。

grep -ci "select" $line

我尝试过,但是没有用。我也试过

grep -ci "select" "$line"

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

grep: This is where we select from a table.: No such file or directory

1
您需要使用herestring ...<<<"$line" 。该命令grep将改为使用文件
Valentin Bajrami 2014年

Answers:


84

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

$ echo "$line" | grep select

...或此处的字符串 ...

$ grep select <<< "$line"

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

$ echo "$line" | tr ' ' '\n' | grep select

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

$ echo "$line" | grep -o select

如果有匹配项,这将使您摆脱该行的其余部分。

编辑:糟糕,阅读得太快了,谢谢Marco。为了计算发生的次数,只需将其中的任何一个管道输送到wc(1);)

lzkata评论后进行的另一项编辑,引用$line时使用echo


3
由于OP希望计算字符串的出现次数,因此您可以添加a wc来完成任务:grep -o <string> <<< "$variable" | wc -l
Marco

2
使用echo "$line"保留现有换行符与创造者,而不是tr
Izkata

Here String的可用性是什么?是否需要Bash或其他Shell?

根据Wikipedia的介绍,这里的字符串可以使用bash,ksh和zsh(但我假设可能还有其他字符串)。
约翰·史密斯

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

您无需呼吁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

它需要2或3个args。提供更多的内容将扭曲其结果。您可以像这样使用它:

_occur=0; occur ... . 2 && echo "count: $_occur"

... 如果出现至少2次....则显示in的出现次数。像这样:

count: 3

如果$_occur为空或unset在调用时为空,则它将完全不影响任何shell变量,return如果"$2"发生的"$1"次数少于1 ,则将影响1 "$3"。或者,如果仅使用两个args进行调用,则return仅当"$2"not in 时才为1 "$1"。否则返回0。

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

occur '' . && echo yay || echo shite

...打印...

shite

...但...

occur . . && echo yay || echo shite

...将打印...

yay

您也可以写一些不同的地方$2,并在(*"$2"*)and "${1#*"$2"}"语句中都省略引号。如果这样做,则可以使用shell glob进行匹配,例如sh[io]te匹配测试。


1
+1:确实更快。在bashdash/ sh(可能还有其他几个)中工作。
约翰·史密斯

@JohnWHSmith-编辑效果更好,但仍可移植。
mikeserv
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.