9

これが私の状況です。現在、本の名前と章の名前の 2 つの引数を受け取るスクリプトがあります。例えば:

$ myscript book1 chap1

さて、説明すると長くなる理由から、スクリプトが次の形式の単一の引数を取ることができるようにしたいと思います: {book name}.{chapter name}。例えば:

$ myscript book1.chap1

私にとって難しいのは、文字列 $1=abc.xyz を取得して、それを $var1=abc と $var2=xyz という 2 つの個別の変数に変換する方法がわからないことです。これどうやってするの?

4

6 に答える 6

17

タグが 2 つだけの場合は、bash 式を使用できます

arg=$1
beforedot=${arg%.*}
afterdot=${arg#*.}

cutシェル組み込みなのでより高速です。これにより、最初の最後のドットの前のすべてが に配置されbeforedot、その後のすべてが に配置されることに注意してくださいafterdot

編集

任意の数のトークンで分割したい場合は、置換/再解釈構造もあります。

string=a.b.c.d.e
tokens=(${string//\./ })

ドットをスペースに置き換えていると、括弧で囲まれているため、配列の宣言と定義として解釈されます。

ただし、これは bash の兄弟や子孫への移植性が低いことがわかりました。たとえば、私のお気に入りのシェルでは動作しませんzsh

配列は中かっこで逆参照する必要があり、0 からインデックスが付けられます。

echo "Third token: ${tokens[2]}"

[@] を使用して配列全体を逆参照することで、それらをループすることもできます。

for i in ${tokens[@]}
do
    # do stuff
done
于 2012-07-10T15:02:09.767 に答える
2

完全を期すために、正規表現方法について尋ねたので:

pattern='^([^.]*)\.(.*)'
[[ $1 =~ $pattern ]]
book=${BASH_REMATCH[1]}
chapter=${BASH_REMATCH[2]}

BASH_REMATCHキャプチャ グループは、配列内の要素です。要素 0 には一致全体が含まれます。

この正規表現は、最初の要素の最初のドットまでキャプチャします。後続のドットを含む最初のドットの後のすべては、2 番目の要素になります。正規表現は、必要に応じて最後のドットで改行するように簡単に変更できます。

于 2012-07-11T01:38:38.383 に答える
1

$arg含まれている場合book.chap

read BOOK CHAP<<<$(IFS="."; echo $arg)

それに応じて、変数 BOOK および CHAP が設定されます。これは、bash が単語境界を理解する方法を制御する bash 内部フィールド区切り文字 (IFS) を使用します。(たとえば) 元のファイルに複数のセパレータがある場合$argは、結果を含めるためにさらに変数を指定するだけです。

ここから:

$IFS のデフォルトは空白 (スペース、タブ、および改行) ですが、たとえば、コンマ区切りのデータ ファイルを解析するために変更される場合があります。

于 2012-07-10T15:05:40.983 に答える
0

シェル パラメーター展開によるパターン置換

やろうとしていることを達成する方法はたくさんあります。他の回答でカバーされていない方法の 1 つは、パターン置換です。

値がピリオドで常に正しく分割されることがわかっている場合は、値にパターン置換を適用して、IFSで簡単にトークン化できます。例えば:

set -- foo.bar
myvar="${1/./ }"
echo $myvar

これにより が得られfoo barます。

于 2012-07-10T15:27:48.950 に答える
0

かっこを使用して 2 つの部分をキャプチャできます。その後、後方参照を使用してそれらを再度取得できます。構文は言語によって異なります。一般的な後方参照に関するレッスンについては、http://www.regular-expressions.info/brackets.htmlを確認してください。

于 2012-07-10T15:00:32.683 に答える
0
#!/bin/bash

book=${1%.*}
chapter=${1#*.}

printf 'book: %s\nchapter: %s\n' "$book" "$chapter"
于 2012-07-10T15:04:07.490 に答える