文字列操作

この章では、Bash 文字列操作の構文を紹介します。

文字列の長さ

文字列の長さを取得するための構文は次のとおりです。

${#変数名}

以下に例を示します。

$ myPath=/home/cam/book/long.file.name
$ echo ${#myPath}
29

中括弧 {} は必須です。そうでない場合、Bash は $# をスクリプト内のパラメーターの数として解釈し、変数名をテキストとして解釈します。

$ エコー $#myvar
0マイバール

上の例では、Bash は $#myvar を別々に解釈します。

部分文字列

文字列から部分文字列を抽出するための構文は次のとおりです。

${変数名:オフセット:長さ}

上記の構文の意味は、変数 $varname の部分文字列を、位置 offset (0 から数えて) から開始し、長さが length であることを返します。

$ count=フロッグフットマン
$ echo ${カウント:4:4}

上の例は、文字列 frogfootman の位置 4 から始まる長さ 4 の部分文字列 foot を返します。

この構文は文字列を直接操作できません。変数を介して文字列を読み取ることのみが可能であり、元の文字列は変更されません。

# エラーを報告する
$ echo ${"こんにちは":2:3}

上の例では、"hello" は変数名ではないため、Bash はエラーを報告します。

length を省略した場合は、offset の位置から開始し、文字列の末尾に戻ります。

$ count=フロッグフットマン
$ エコー ${カウント:4}
召使い

上記の例は、変数 count の位置 4 から最後までの部分文字列を返します。

「offset」が負の値の場合は、文字列の末尾から数えることを意味します。 ${variable:-word} で変数のデフォルト値を設定するための構文との混乱を避けるために、負の数値の前にスペースを置く必要があることに注意してください。このとき、「length」を指定することもできます。「length」には正の値または負の値を指定できます(負の値は「offset」の長さを超えることはできません)。

$ foo="この文字列は長いです。"
$ echo ${foo: -5}
長さ。
$ echo ${foo: -5:2}
やあ
$ echo ${foo: -5:-2}
ロン

上記の例では、offset-5 です。これは、最後から 5 番目の文字からインターセプトが開始されることを意味するため、long. が返されます。指定された長さ length2 の場合は lo が返され、length-2 の場合は文字列の末尾から 2 文字が除外されることを意味するため、 lon が返されます。戻ってきました。

検索と置換

Bash には、文字列の検索と置換のためのメソッドがいくつか用意されています。

**(1) 文字列ヘッダーのパターン マッチング。 **

次の 2 つの構文は、文字列の先頭が指定されたパターンに一致するかどうかをチェックできます。一致が成功した場合は、一致した部分が削除され、残りの部分が返されます。元の変数は変更されません。

# pattern が変数 variable の先頭と一致する場合、
# 最も短い一致(非貪欲一致)部分を削除し、残りの部分を返します
${変数#パターン}

# pattern が変数 variable の先頭と一致する場合、
# 最長一致(貪欲一致)部分を削除し、残りの部分を返す
${変数##パターン}

上記 2 つの構文は、変数文字列の先頭の一致する部分を削除し (何も置き換えず)、残りの部分を返します。違いは、1 つは最短一致 (非貪欲一致とも呼ばれます) であり、もう 1 つは最長一致 (貪欲一致とも呼ばれます) であることです。

一致パターン pattern では、*?[] などのワイルドカード文字を使用できます。

$ myPath=/home/cam/book/long.file.name

$ echo ${myPath#/*/}
cam/book/long.file.name

$ echo ${myPath##/*/}
長いファイル名

上の例では、一致パターンは /*/ です。ここで * は任意の数の文字に一致するため、最も短い一致は /home/ で、最も長い一致は /home/cam/book/ です。 。

以下の記述方法により、ファイルパスのディレクトリ部分を削除し、ファイル名だけを残すことができます。

$ path=/home/cam/book/long.file.name

$ echo ${パス##*/}
長いファイル名

上記の例では、パターン */ がディレクトリ部分に一致するため、ファイル名のみが返されます。

別の例を見てみましょう。

$phone="555-456-1414"
$ echo ${電話番号*-}
456-1414
$ echo ${電話##*-}
1414

一致が失敗した場合は、元の文字列が返されます。

$phone="555-456-1414"
$ エコー ${電話#444}
555-456-1414

上記の例では、パターン「444」は元の文字列では一致しないため、そのまま返されます。

ヘッダーの一致部分を他の内容に置き換えたい場合は、以下の記述方法を使用してください。

# パターンは文字列の先頭になければなりません
${変数/#パターン/文字列}

# 例
$ foo=JPG.JPG
$ echo ${foo/#JPG/jpg}
jpg.JPG

上記の例では、置換された JPG は文字列の先頭にある必要があるため、jpg.JPG が返されます。

**(2) 文字列の末尾でのパターン マッチング。 **

次の 2 つの構文は、文字列の末尾が指定されたパターンに一致するかどうかをチェックできます。一致が成功した場合は、一致した部分が削除され、残りの部分が返されます。元の変数は変更されません。

# パターンが変数変数の末尾に一致する場合、
# 最も短い一致(非貪欲一致)部分を削除し、残りの部分を返します
${変数%パターン}

# パターンが変数変数の末尾に一致する場合、
# 最長一致(貪欲一致)部分を削除し、残りの部分を返す
${変数%%パターン}

上記の 2 つの構文は、変数文字列の末尾の一致する部分を削除し (何も置き換えず)、残りの部分を返します。違いは、1 つは最短一致 (非貪欲一致とも呼ばれます) であり、もう 1 つは最長一致 (貪欲一致とも呼ばれます) であることです。

$ path=/home/cam/book/long.file.name

$ echo ${path%.*}
/home/cam/book/long.file

$ echo ${path%%.*}
/ホーム/カメラ/本/ロング

上の例では、一致パターンは .* で、* は任意の数の文字に一致するため、最短一致は .name、最長一致は .file.name です。

以下の記述方法により、パスのファイル名部分を削除し、ディレクトリ部分のみを残すことができます。

$ path=/home/cam/book/long.file.name

$ echo ${path%/*}
/ホーム/カメラ/本

上記の例では、パターン /* がファイル名部分と一致するため、ディレクトリ部分のみが返されます。

以下の記述方法で拡張子を置き換えることができます。

$ ファイル=foo.png
$ echo ${file%.png}.jpg
foo.jpg

上記の例では、ファイル拡張子を .png から .jpg に変更します。

別の例を見てみましょう。

$phone="555-456-1414"
$ echo ${phone%-*}
555-456
$ echo ${phone%%-*}
555

一致が失敗した場合は、元の文字列が返されます。

末尾の一致部分を他の内容に置き換えたい場合は、以下の記述方法を使用してください。

# パターンは文字列の末尾に出現する必要があります
${変数/%パターン/文字列}

# 例
$ foo=JPG.JPG
$ echo ${foo/%JPG/jpg}
JPG.jpg

上記の例では、置換された JPG は文字列の末尾にある必要があるため、JPG.jpg が返されます。

**(3) 任意の位置でのパターンマッチング。 **

次の 2 つの構文は、文字列の内部が指定されたパターンに一致するかどうかをチェックできます。一致した場合は、一致した部分が削除され、別の文字列として返されます。元の変数は変更されません。

# pattern が変数 variable の一部と一致する場合、
# 最長一致(貪欲一致)の部分は文字列に置換されますが、最初に一致したもののみが置換されます
${変数/パターン/文字列}

# pattern が変数 variable の一部と一致する場合、
# 最長一致(貪欲一致)の部分を文字列に置換し、一致したものをすべて置換
${変数//パターン/文字列}

上記の 2 つの構文は、最長一致 (貪欲一致) による置換です。違いは、前者の構文は最初の一致のみを置換し、後者の構文はすべての一致を置換することです。

$ path=/home/cam/foo/foo.name

$ echo ${パス/foo/bar}
/home/cam/bar/foo.name

$ echo ${path//foo/bar}
/home/cam/bar/bar.name

上記の例では、前者のコマンドは最初の foo のみを置き換え、後者のコマンドは両方の foo を置き換えます。

次の例では、区切り文字を「:」から改行文字に変更します。

$ echo -e ${PATH//:/'\n'}
/usr/local/bin
/usr/bin
/bin
...

上記の例では、「echo」コマンドの「-e」パラメータは、置換された文字列の「\n」文字が改行文字として解釈されることを意味します。

パターン部分にはワイルドカードが使用できます。

$phone="555-456-1414"
$ echo ${phone/5?4/-}
55-56-1414

上の例では、「5-4」を「-」に置き換えます。

string部分を省略した場合は、一致する部分を空の文字列に置き換えること、つまり一致する部分を削除することと同じになります。

$ path=/home/cam/foo/foo.name

$ echo ${パス/.*/}
/ホーム/カム/フー/フー

上記の例では、2 番目のスラッシュ以降の string 部分が省略されているため、パターン .* に一致する .name の部分が削除されて返されます。

前述したように、この構文には 2 つの拡張形式があります。

# パターンは文字列の先頭になければなりません
${変数/#パターン/文字列}

# パターンは文字列の末尾に出現する必要があります
${変数/%パターン/文字列}

大文字と小文字を変更する

次の構文は変数の大文字と小文字を変更します。

# 大文字に変換
${変数名^^}

# 小文字に変換
${変数名,,}

以下に例を示します。

$ foo=heLLo
$ エコー ${foo^^}
こんにちは
$ echo ${foo,,}
こんにちは

作者: wangdoc

アドレス: https://wangdoc.com/

ライセンス: クリエイティブ・コモンズ 3.0