重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

下記のシェル関数 arg_space() 内で、grepを使いたいのですが。
'aaa bbb' などのスペースを含む文字列を引数として渡すとスペース後の文字列がファイル名と
認識されてしまいます。

-- arg_space.sh --
#!/bin/bash

CHK_STR='aaa bbb'
FILE_NAME='data/aaa.txt'

function arg_space() {

return `grep -c $1 $2`

}
arg_space $CHK_STR $FILE_NAME

if [ $? -ge 1 ];
then
echo 'Match !!'
else
echo 'No match.'
fi

exit 0
------------------

]# ./arg_space.sh
grep: bbb: No such file or directory
Match !!

スペース文字を、grep に区切り文字として認識させないようにする
方法を教えて 頂けないでしょうか。


-- data/aaa.txt --
aaa bbb ccc ddd
---------------

A 回答 (1件)

return `grep -c "$1" "$2"`


arg_space "$CHK_STR" "$FILE_NAME"


シェルでは、変数の展開をしてから、コマンドの実行となります。
arg_space $CHK_STR $FILE_NAME

arg_space aaa bbb data/aaa.txt
となり、この時点で
$1=aaa
$2=bbb
$3=data/aaa.txt
となっています。
この状態では、function arg_spaceで対策のしようがありません。

ここを解決しても、
grep -c $1 $2

grep -c aaa bbb data/aaa.txt
となり、やはりaaa bbb をまとめて扱いません。

引用符を付けることで、空白までまとめることができます。


あとは、ファイルが無い等でgrepが何も返さなかった場合、 return が引数無しで実行されます。
これが、 $? に適当な値が入ってしまう理由です。
grepがエラーの場合は0を返す、等の工夫が必要でしょう。



#!/bin/bash -x
と -x オプションを付けると、変数展開等の処理が済んだあとの、実際に実行しているコマンドが出力されます。
デバッグ時には活用しましょう。

実行例)
○もとのままの場合
+ CHK_STR='aaa bbb'
+ FILE_NAME=data/aaa.txt
+ arg_space aaa bbb data/aaa.txt ← ここで既にaaa bbb と分割されていることがわかる
++ grep -c aaa bbb ← $1がaaa,$2がbbbになっていて、ファイル名が使われていないがわかる
grep: bbb: No such file or directory
+ return ← grepでエラーになると、引数無しでreturn していることがわかる
+ '[' 2 -ge 1 ']' ←$? が 2 になってしまっていることがわかる。
+ echo 'Match !!'
Match !!
+ exit 0

○arg_space "$CHK_STR" "$FILE_NAME" だけ変更
+ CHK_STR='aaa bbb'
+ FILE_NAME=data/aaa.txt
+ arg_space 'aaa bbb' data/aaa.txt ← ''が付いていて、空白込みで1つになっていることがわかる
++ grep -c aaa bbb data/aaa.txt ← こちらは、''が無いのでaaaとbbbが分割されている
grep: bbb: No such file or directory
+ return data/aaa.txt:0 ← bbb, data/aaa.txtの2つのファイルが指定されたので、grepはファイル名付きで出力する。
./arg_space.sh: line 8: return: data/aaa.txt:0: numeric argument required ← returnは数値しか受けつけないのでエラーになる
+ '[' 255 -ge 1 ']' ← エラーになったので、$?が期待とは違う
+ echo 'Match !!'
Match !!
+ exit 0

○grepの方も対策した場合
+ CHK_STR='aaa bbb'
+ FILE_NAME=data/aaa.txt
+ arg_space 'aaa bbb' data/aaa.txt ← ''が付いていて、空白込みで1つになっていることがわかる
++ grep -c 'aaa bbb' data/aaa.txt ← ''が付いていて、空白込みで1つになっていることがわかる
+ return 0 ← 数値だけになった
+ '[' 0 -ge 1 ']'
+ echo 'No match.'
No match.
+ exit 0
    • good
    • 0
この回答へのお礼

丁寧に回答いただきまして大変勉強になります。
上記の方法で、解決しました。

デバッグの方法、これから活用していきたいと思います。
本当にありがとうございました。_( . . )_

お礼日時:2014/08/23 17:45

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!