web-dev-qa-db-ja.com

変数のgrep

変数があるとしましょう

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

ここで、selectが文で何回発生するかをgrepしたいと思います。

grep -ci "select" $line

私はそれを試しましたが、うまくいきませんでした。私も試しました

grep -ci "select" "$line"

それでも動作しません。次のエラーが表示されます。

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

標準入力でgrepを読み取らせます。 a pipe ...を使用します.

_$ echo "$line" | grep select
_

...または ここの文字列 ...

_$ grep select <<< "$line"
_

また、greppingの前にスペースを改行で置き換えることもできます。

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

...またはgrepに一致のみを印刷するように要求できます:

_$ echo "$line" | grep -o select
_

これにより、一致したときに行の残りの部分を取り除くことができます。

編集:おっと、少し速すぎます、ありがとう Marco 。発生をカウントするには、これらのパイプを wc(1) ;)にパイプするだけです。

lzkata のコメントの後に別の編集を行い、echoを使用する場合は_$line_を引用します

102
John WH Smith
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つの引数が必要です。それ以上のものを提供すると、結果が歪められます。次のように使用できます。

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

....内の...の出現回数を2回以上発生した場合に出力します。このような:

count: 3

$_occurが空の場合、またはunsetが呼び出された場合は、シェル変数にはまったく影響しません。"$2""$1"で発生した場合、return 1 "$3"回未満。または、2つの引数のみで呼び出された場合、"$2""$1"にない場合にのみ、return 1になります。そうでなければ0を返します。

したがって、最も簡単な形式では、次のことができます。

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

...印刷する...

shite

...だが...

occur . . && echo yay || echo shite

...印刷されます...

yay

また、少し書き方を変えて、$2(*"$2"*)ステートメントの両方で"${1#*"$2"}"を囲む引用符を省略してもかまいません。これを行うと、一致テストにsh[io]teなどの一致にシェルグロブを使用できます。

7
mikeserv