web-dev-qa-db-ja.com

bashの関数引数としてスペースを含む文字列を渡す

私はスペースを含む文字列をbashスクリプトの関数に渡す必要があるbashスクリプトを書いています。

例えば:

#!/bin/bash

myFunction
{
    echo $1
    echo $2
    echo $3
}

myFunction "firstString" "second string with spaces" "thirdString"

実行すると、予想される出力は次のとおりです。

firstString
second string with spaces
thirdString

ただし、実際に出力されるのは次のとおりです。

firstString
second
string

Bashの関数に単一の引数としてスペースを含む文字列を渡す方法はありますか?

143
Grant Limberg

引用符を付ける必要があり、また、関数宣言が間違っています。

myFunction()
{
    echo "$1"
    echo "$2"
    echo "$3"
}

そして、他の人と同じように、それは私にも機能します。使用しているシェルのバージョンを教えてください。

146
ghostdog74

上記の問題に対する別の解決策は、各文字列を変数に設定し、リテラルのドル記号\$で示される変数で関数を呼び出すことです。次に、関数でevalを使用して変数を読み取り、期待どおりに出力します。

#!/usr/bin/ksh

myFunction()
{
  eval string1="$1"
  eval string2="$2"
  eval string3="$3"

  echo "string1 = ${string1}"
  echo "string2 = ${string2}"
  echo "string3 = ${string3}"
}

var1="firstString"
var2="second string with spaces"
var3="thirdString"

myFunction "\${var1}" "\${var2}" "\${var3}"

exit 0

出力は次のとおりです。

    string1 = firstString
    string2 = second string with spaces
    string3 = thirdString

これと同様の問題を解決しようとして、私は自分の変数がスペース不足であると考えるUNIXの問題にぶつかりました。 awkを使用して関数にパイプ区切り文字列を渡して、後でレポートの作成に使用される一連の変数を設定しようとしました。最初にghostdog74によって投稿されたソリューションを試しましたが、すべてのパラメーターが引用符で囲まれていないため、動作させることができませんでした。各パラメーターに二重引用符を追加した後、期待どおりに機能し始めました。

以下は、私のコードの前の状態であり、状態の後に完全に機能しています。

変更前-機能していないコード

#!/usr/bin/ksh

#*******************************************************************************
# Setup Function To Extract Each Field For The Error Report
#*******************************************************************************
getField(){
  detailedString="$1"
  fieldNumber=$2

  # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} 
  #   And Strips Leading And Trailing Spaces
  echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//'
}

while read LINE
do
  var1="$LINE"

  # Below Does Not Work Since There Are Not Quotes Around The 3
  iputId=$(getField "${var1}" 3)
done<${someFile}

exit 0

後-機能コード

#!/usr/bin/ksh

#*******************************************************************************
# Setup Function To Extract Each Field For The Report
#*******************************************************************************
getField(){
  detailedString="$1"
  fieldNumber=$2

  # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} 
  #   And Strips Leading And Trailing Spaces
  echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//'
}

while read LINE
do
  var1="$LINE"

  # Below Now Works As There Are Quotes Around The 3
  iputId=$(getField "${var1}" "3")
done<${someFile}

exit 0
17
TheBanjoMinnow

この問題の最も簡単な解決策は、シェルスクリプトを実行するときにスペースで区切られた引数に\"を使用するだけです。

#!/bin/bash
myFunction() {
  echo $1
  echo $2
  echo $3
}
myFunction "firstString" "\"Hello World\"" "thirdString"
6
Piyush Aggarwal

MyFunctionの定義が間違っています。そのはず:

myFunction()
{
    # same as before
}

または:

function myFunction
{
    # same as before
}

とにかく、Bash 3.2.48で見た目は良く、うまく動作します。

5

私は9年遅れていますが、よりダイナミックな方法は

function myFunction 
{
   for i in $*; do echo $i; done;
}
1
Raimi bin Karim

私のために働いたシンプルなソリューション-$ @

Test(){
   set -x
   grep "$@" /etc/hosts
   set +x
}
Test -i "3 rb"
+ grep -i '3 rb' /etc/hosts

実際のgrepコマンドを確認できました(-xを設定していただきありがとうございます)。

1