シェルスクリプトで空白の前後に文字列を分割する方法は?

シェルスクリプトで空白の前後に文字列を分割する方法は?

以下のように、echoに変数が表示されます。

$ echo $var
129 148

出力値として129のみ取る必要があります。 129と148をどのように分けますか?

答え1

またJason Urineのアドバイス、あなたはそれを使用することができますcut

echo $var | cut -d' ' -f1

上記のcut出力は、echoスペース区切り記号()を使用して-d' '最初のフィールド(-f1)を出力します。

答え2

賢い方法は、bash配列を使用して文字列をスペースに分割することです。括弧を使用して簡単に配列を宣言できます。

var="129 148     181"
vars=( $var )
echo "First  word of var: '${vars[0]}'"
echo "Second word of var: '${vars[1]}'"
echo "Third  word of var: '${vars[2]}'"
echo "Number of words in var: '${#vars[@]}'"

答え3

長い話を短く

${var%% *}

$ echo "$var"
129 148
$ echo "${var%% *}"
129

コメント

echo "${var% *}" && echo "${var#* }"... – ジェイソンウリアン

あなたの質問に答える方法は数多くありますが、最も簡単な方法はパラメータ拡張です。これはJasonがコメントで提案したものです。私はこれがこの問題を解決する正しいツールだと思います。

cutところで、ここにある他の答えには何の問題もありません(パイプから配列に、配列に分割)。次の問題をより簡単に解決できる多目的ソリューションです。「では、2番目またはn番目の数字はどのようにわかりますか?」単純な質問は、長い間単純に維持されることはほとんどありません。

欠点

このアプローチはどこでも動作しないかもしれませんが、そうでない場所を見つけるのは難しいです。もちろん、bashほとんどのUnixシステムではデフォルトの対話型シェルで実行され、zshMacOSではデフォルトの対話型シェルで実行されます。壊れると予想されるものと壊れると予想されるashように、ルーターに見られる制限付きシェルもdashパラメータ拡張を使用するとうまく機能します。

${var%% *}対照に関する注意${var% *}

Jasonが提案したシンボルの代わりに2%のシンボルを使用したことがわかります。違い%%最長一致文字列の%合計最短。たとえば、var3つの数字を含めると、次のように表示されます。

$ echo "$var"
129 148 167
$ echo "${var%% *}"
129
$ echo "${var% *}"
129 148

さらなる読書のために

ここまで来たら、「パラメータの拡張という魔法についてどこでもっと学べますか?」と気になるでしょう。これに対する答えはシェル文書で確認できますman bash。たとえば、関連セクションから抜粋した内容があります。パラメータ拡張bashマンページから:

一致するプレフィックスパターンを削除します。

${範囲#言葉}

${範囲##言葉}

これ 言葉 パス名拡張と同様に、パターンを生成するように拡張され、拡張された値と一致します。 範囲 下記のルールを使用してください。 パターンマッチング。パターンが値の先頭に一致する場合 範囲、拡張結果は拡張値です。 範囲 最も短い一致パターン( '#「大文字と小文字」または最長の一致パターン(「##「ケース)が削除されました。もし 範囲 はい @ または *、パターン除去操作が各位置引数に順番に適用され、拡張が結果リストです。もし 範囲 配列変数で、下付き文字は次のとおりです。 @ または *、パターン削除操作が配列の各メンバーに順番に適用され、拡張が結果リストです。

一致するサフィックスパターンを削除します。

${範囲%言葉}

${範囲%%言葉}

これ言葉パス名拡張と同様に、パターンを生成するように拡張され、拡張された値と一致します。 範囲 下記のルールを使用してください。 パターンマッチング。パターンが拡張値の末尾部分と一致する場合 範囲、拡張結果は拡張値です。 範囲 最も短い一致パターン( '%「大文字と小文字」または最長の一致パターン(「%%「ケース)が削除されました。もし 範囲 はい @ または *、パターン除去操作が各位置引数に順番に適用され、拡張が結果リストです。もし 範囲 配列変数で、下付き文字は次のとおりです。 @ または *、パターン削除操作が配列の各メンバーに順番に適用され、拡張が結果リストです。

答え4

次のようにsetコマンドを使用して、スペースに沿って変数を分割できます。

IFS=" "
set -- $var
echo $1
129

関連情報