シェル関数引数のスペース文字列をgrepに

このQ&Aのポイント
  • シェル関数 arg_space() 内で、grepを使いたいのですが。'aaa bbb' などのスペースを含む文字列を引数として渡すとスペース後の文字列がファイル名と認識されてしまいます。
  • スペース文字を、grep に区切り文字として認識させないようにする方法を教えて 頂けないでしょうか。
  • ./arg_space.sh grep: bbb: No such file or directory Match !! スペース文字を、grep に区切り文字として認識させないようにする方法を教えて 頂けないでしょうか。
回答を見る
  • ベストアンサー

シェル関数引数のスペース文字列をgrepに

下記のシェル関数 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 ---------------

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.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

gahosky
質問者

お礼

丁寧に回答いただきまして大変勉強になります。 上記の方法で、解決しました。 デバッグの方法、これから活用していきたいと思います。 本当にありがとうございました。_( . . )_

関連するQ&A

  • bashの関数の引数にスペースが入るとズレる件

    bashの関数の引数にスペースが入るとズレる件 bashの関数の引数にスペースが入ると、引数が分離して、位置がズレてしまいます。 これを回避する方法はありませんか? ■aaa.sh-Top #!/bin/bash declare FuncPara1 declare FuncPara2 function f_echo() { echo 'uf_echo1='$1 echo 'uf_echo2='$2 echo 'uf_echo3='$3 } echo '---test1---' FuncPara1='aaabbb' FuncPara2='ccc' f_echo ${FuncPara1} ${FuncPara2} echo '---test2---' FuncPara1='aaa bbb' FuncPara2='ccc' f_echo ${FuncPara1} ${FuncPara2} ■aaa.sh-Bottom ■aaa.shの実行 # ./aaa.sh ---test1--- uf_echo1=aaabbb uf_echo2=ccc uf_echo3= ---test2--- uf_echo1=aaa uf_echo2=bbb uf_echo3=ccc このtest2の時に、 ---test2--- uf_echo1=aaa bbb uf_echo2=ccc uf_echo3= となって欲しい。 もしくは、何かしら「なったテイ」で、 引数1の値は「aaa bbb」 引数2の値は「ccc」 と関数側で判断できる方法はありませんか?

  • シェルスクリプトで読み込んだ文字列の区切り文字以降の文字列を取得したい

    ちょっと説明が難しいのですが aaa = bbb こういう文字列の右側のbbbを取り出したいのですが可能ですか? 全てこのようなら問題ないのですが、前後のスペースに問題があります _aaa = bbb や aaa=bbb aaa =__bbb アンダーバーはスペースのかわりです。 のように前後にスペースが1つ2つ入っていたり抜けていたりします。 aaa = bbb だったら i=`echo | sed 's/aaa\ =\ //'` のようにして取得できていますが、その他の処理がうまくできません そもそもシェルスクリプトでこのような処理は無理なのでしょうか? perl ではできたのですができればシェルスクリプトで完結させたいのです。 よろしくお願いします。 使っているシェルはzshです。

  • 指定文字列を空文字に

    教えてください。 文字列(数字)に含まれる「,」を空白文字に変換しようと思い、下記のように記述しましたがうまくいきません。 $aaa='11,,111'; $bbb = str_replace($aaa,'',','); $bbbには「,」が返ってきてしまいます。$aaaは「11,,111」のままです。 $bbbに「11111」という値が返ってきてほしいのですが、どうすればよいでしょうか? どうかご教授ください。

    • ベストアンサー
    • PHP
  • Perlの文字列置換について

    Perlで文字列置換の業務をすることになりした。 Struts1からStruts2のJSPのタグの変換です。 (1)html:textarea property="aaa" styleClass="bbb" (2)s:textarea name="aaa" cssClass="bbb" (1)から(2)に変換したいです。 「html:textarea」が「s:textarea」に対応しており、その属性の「property="aaa"」が「name="aaa"」に対応、 「styleClass="bbb"」が「cssClass="bbb"」に対応するといった内容です。 aaaとbbbは任意の文字列 if ($str =~ /html:textarea/ ) { $str =~ s/html:textarea/s:textarea/; $str =~ s/property=\"(.+)\"/name="$1"/; $str =~ s/styleClass=\(.+)"\"/cssClass/; というように参考書を元に作成してみたのですが、変換は行われるものの、属性のpropertyとstyleClassの順番が逆だったり、ここに記載していない他の属性を間に入れたりすると変換ができません。 どなたか教えて下さい。

    • ベストアンサー
    • Perl
  • system関数と引数について

    環境 Windows XP VC++6.0, Win32consoleです。 以下のファイルを連続処理させたいのですが、  aaa1.txt、aaa2.txt、aaa3.txt、~~~~aaa.15.txt  bbb1.txt、bbb2.txt、bbb3.txt、~~~~bbb.15.txt  ccc1.txt、ccc2.txt、ccc3.txt、~~~~ccc.15.txt その際、perlで処理させたいと考えております。 VC++ から system関数を用いてperlファイルを動かそうとしていますが、 たとえば、この時 aaa や bbb や ccc を引数として渡せるのでしょうか?

  • 文字列の中間位置にマッチするアサーション表現

    文字列の中間位置にマッチするアサーション表現 qr{ ^ \w+ \s+ \d+ \s+ \d+ $ }xms の規則で $strに文字列が複数行格納されています。 スペースの個数に関しては任意です。 my $str = <<EOF ; BBB 0 00 AAA 1 01 AAA 2 10 : EOF 上記例で行頭がAAAで始まる、末尾の連続した数字の先頭にマッチする正規表現を教えて頂けないでしょか? AAA 1 01 の01の先頭に位置にマッチするアサーションを知りたい 後読みを用いたいのですが、空白の数が任意のためうまく書けずに困ってます。

    • ベストアンサー
    • Perl
  • アスタリスクを文字列として変数に入れるには

    HP-UX cshで、アスタリスクを文字列として 変数に入れるにはどうしたら良いでしょうか? 現在は <file3の中身> grep -v file*.txt | grep -v file2.txt で、 set hensu=`cat file3.txt`としてecho $hensuすると grep -v file1.txt file2.txt file3.txt | grep -v file2.txt という具合に、アスタリスクがワイルドカードとして 働きます。これを「file*.txt」という文字列として 変数に入れる方法を教えてください。 宜しくお願いします。

  • ''で囲まれていない文字列にマッチする正規表現

    下記のような文字列($str)に対して置換を行い、 my $str = qq{ AAA = BBB - 'CCC' }; $str =~ s/★正規表現★/sprintf("DDD(%s)",$1)/xmsge ; 変換後 $str = DDD(AAA) = DDD(BBB) - 'CCC' ; を実現する★正規表現★を書きたいと思っています。  ・AAA,BBB,CCCは[\w]で構成される文字列です。 ですが、シングルクォーテーション('')で囲まれていない文字列にマッチする正規表現が書けなく困っています。 一度、シングルクォーテーションで囲まれているものも含めて全てDDD()をつけて、そのあとで、シングルクォーテーションを含むものは元に戻すことでやりたいことは実現できているのですが、1行で実現できる方法を探しています。 アドバイスよろしくお願いします。

    • ベストアンサー
    • Perl
  • バッチファイルの正規表現を利用した文字列検索

    お世話になっております。 表題の件について、質問させてください。 『とあるファイルに記述されている文字列を一部抜き出して、 別ファイルとして保存する』というバッチファイルを作成していますが、 うまく抜き出すことができないため、ご教示いただければ幸いです。 例) ・filelist.txt .\aaa\aaa.txt .\aaa\bbb.txt 上記ファイルに対し、「.\aaa\aaa.txt」の一行のみ取り出した 「aaafile.txt」というファイルを生成したいと考えております。 現在、私が考えたコマンドは下記になります。 for /f %%A in ('findstr /r /c:"aaa[^\\].*" filelist.txt') do echo %%A > aaafile.txt このコマンドを実行すると、「.\aaa\bbb.txt」まで抽出してしまい、 意図通りとなりません。 初歩的なミスかもしれませんが、 何卒、よろしくお願いいたします。

  • シェルの引数を、実行するパラメータに指定するには?

    シェル初心者です。 シェルの実行パラメータを、その中で実行する処理のパラメータに再び指定したいのですが可能でしょうか。 ただし、パラメータの数は可変です。 環境はSolarisです。 aaa.sh aaa bbb ccc aaa.shの中 bbbコマンド aaa bbb ccc ということを行いたいです。 パラメータ数が固定であれば問題なさそうですが 可変の場合、どのような記述をすればよいでしょうか?

専門家に質問してみよう