いろいろ備忘録日記

主に .NET とか Go とか Python絡みのメモを公開しています。

シェルスクリプトメモ-01 (ブレース展開, brace expansion)

概要

以下、自分用メモです。

bashのブレース展開について、よく忘れるのでメモメモ。

ブレース展開って?

ブレース展開は、{ } の中に書かれた一個以上のカンマで区切られた複数の文字列を左から順番に使用して文字列を生成する機能。

例えば、

  • hello/{1,2,3}

とすると

  • hello/1
  • hello/2
  • hello/3

と展開されます。

連続する値を生成する場合は .. (ドット2つ) で範囲を一気に指定できます。

先程の例でいうと

  • hello/{1,2,3}

  • hello/{1..3}

でも表現可能。

ブレース展開は、シェル ( bash )における各種展開処理の一番最初に処理される項目となっています。

また、パス名展開とは異なり、パス名との照合は行われません。なので、実在していないパスとなっても構わない。

シーケンスな値を展開

#!/usr/bin/env bash

# Brace Expansion -- ブレース展開の sequence expressions のサンプルです.
#
# ブレース展開について
#   - Prefix{Range}Postfix
#     - Prefix と Postfix は省略可能
#   - {1..10}とすると 1 から 10 のシーケンスが生成される
#   - {1,3,5,7}のように書くこともできる
#   - {Range} の中でも、通常のワイルドカードが利用できる
#
# REFERENCES:
#   - https://www.putorius.net/bash-brace-expansion.html
#   - https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html
_exec() {
    # 作業用ディレクトリ作成
    basedirpath=/tmp/try-shellscript/brace_expansion/sequence_expression
    rm -rf "${basedirpath}"
    mkdir -p "${basedirpath}"

    # 普通にディレクトリを連続して作成すると以下のようになる
    echo '>> mkdir ${basedirpath}/1 to 3'
    mkdir "${basedirpath}/1"
    mkdir "${basedirpath}/2"
    mkdir "${basedirpath}/3"

    ls -l "${basedirpath}"
    echo '----------------------------'

    # ブレース展開を利用すると以下のように書ける
    echo '>> mkdir -p "${basedirpath}"/{5..9}'
    mkdir -p "${basedirpath}"/{5..9}
    ls -l "${basedirpath}"
    echo '----------------------------'

    # Prefix{Range}Postfix のパターン
    echo '>> touch "${basedirpath}"/testdata-{1..9}.log'
    rm -rf "${basedirpath}"/{1..9}
    touch "${basedirpath}"/testdata-{1..9}.log

    ls -l "${basedirpath}"
    echo '----------------------------'
}

_exec

実行すると以下のようになります。

gitpod /workspace/try-shellscript $ make run
ENTER EXAMPLE NAME: brace_expansion_sequence_expansion

[INPUT ] brace_expansion_sequence_expansion
[TARGET] brace_expansion_sequence_expansion
[SCRIPT] basic/shell_expansions/brace_expansion/sequence_expression.sh

===== START [basic/shell_expansions/brace_expansion/sequence_expression.sh] =====
>> mkdir ${basedirpath}/1 to 3
total 0
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 1
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 2
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 3
----------------------------
>> mkdir -p "${basedirpath}"/{5..9}
total 0
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 1
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 2
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 3
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 5
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 6
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 7
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 8
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:32 9
----------------------------
>> touch "${basedirpath}"/testdata-{1..9}.log
total 0
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-1.log
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-2.log
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-3.log
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-4.log
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-5.log
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-6.log
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-7.log
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-8.log
-rw-r--r-- 1 gitpod gitpod 0 May 10 07:32 testdata-9.log
----------------------------
===== END   [basic/shell_expansions/brace_expansion/sequence_expression.sh] =====

DONE

非シーケンシャルな値を展開

#!/usr/bin/env bash

# Brace Expansion -- ブレース展開の non sequensial expressions のサンプルです.
#
# ブレース展開について
#   - Prefix{Range}Postfix
#     - Prefix と Postfix は省略可能
#   - {1..10}とすると 1 から 10 のシーケンスが生成される
#   - {1,3,5,7}のように書くこともできる
#   - {Range} の中でも、通常のワイルドカードが利用できる
#
# REFERENCES:
#   - https://www.putorius.net/bash-brace-expansion.html
#   - https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html
_exec() {
    # 作業用ディレクトリ作成
    basedirpath=/tmp/try-shellscript/brace_expansion/non_sequensial_expression
    rm -rf "${basedirpath}"
    mkdir -p "${basedirpath}"

    # 非シーケンシャルな指定も可能
    # (注意) 要素の指定時にスペースを開けてはいけない
    #            {1, 3, 5, 7}
    #        上記のようにするとエラーとなる.
    echo '>> mkdir -p "${basedirpath}"/{1,3,5,7}'
    mkdir -p "${basedirpath}"/{1,3,5,7}

    ls -l "${basedirpath}"
    echo '----------------------------'
}

_exec

実行すると以下のようになります。

gitpod /workspace/try-shellscript $ make run
ENTER EXAMPLE NAME: brace_expansion_non_sequensial_expansion

[INPUT ] brace_expansion_non_sequensial_expansion
[TARGET] brace_expansion_non_sequensial_expansion
[SCRIPT] basic/shell_expansions/brace_expansion/non_sequensial_expression.sh

===== START [basic/shell_expansions/brace_expansion/non_sequensial_expression.sh] =====
>> mkdir -p "${basedirpath}"/{1,3,5,7}
total 0
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:34 1
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:34 3
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:34 5
drwxr-xr-x 2 gitpod gitpod 40 May 10 07:34 7
----------------------------
===== END   [basic/shell_expansions/brace_expansion/non_sequensial_expression.sh] =====

DONE

ワイルドカード使用

#!/usr/bin/env bash

# Brace Expansion -- ブレース展開の ワイルドカード指定 のサンプルです.
#
# ブレース展開について
#   - Prefix{Range}Postfix
#     - Prefix と Postfix は省略可能
#   - {1..10}とすると 1 から 10 のシーケンスが生成される
#   - {1,3,5,7}のように書くこともできる
#   - {Range} の中でも、通常のワイルドカードが利用できる
#
# REFERENCES:
#   - https://www.putorius.net/bash-brace-expansion.html
#   - https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html
_exec() {
    # 作業用ディレクトリ作成
    basedirpath=/tmp/try-shellscript/brace_expansion/use_wildcard
    rm -rf "${basedirpath}"
    mkdir -p "${basedirpath}"

    # ワイルドカードの指定も出来る
    echo '>> ls -d "${basedirpath}"/{go*,r???}'
    mkdir -p "${basedirpath}"/{go,golang,dotnet,java,python,ruby,rust}

    ls -d "${basedirpath}"/{go*,r???}
    echo '----------------------------'
}

_exec

実行すると以下のようになります。

gitpod /workspace/try-shellscript $ make run
ENTER EXAMPLE NAME: brace_expansion_use_wildcard

[INPUT ] brace_expansion_use_wildcard
[TARGET] brace_expansion_use_wildcard
[SCRIPT] basic/shell_expansions/brace_expansion/use_wildcard.sh

===== START [basic/shell_expansions/brace_expansion/use_wildcard.sh] =====
>> ls -d "${basedirpath}"/{go*,r???}
/tmp/try-shellscript/brace_expansion/use_wildcard/go
/tmp/try-shellscript/brace_expansion/use_wildcard/golang
/tmp/try-shellscript/brace_expansion/use_wildcard/ruby
/tmp/try-shellscript/brace_expansion/use_wildcard/rust
----------------------------
===== END   [basic/shell_expansions/brace_expansion/use_wildcard.sh] =====

DONE

組み合わせ値を生成

#!/usr/bin/env bash

# Brace Expansion -- ブレース展開の 組み合わせ のサンプルです.
#
# ブレース展開について
#   - Prefix{Range}Postfix
#     - Prefix と Postfix は省略可能
#   - {1..10}とすると 1 から 10 のシーケンスが生成される
#   - {1,3,5,7}のように書くこともできる
#   - {Range} の中でも、通常のワイルドカードが利用できる
#
# REFERENCES:
#   - https://www.putorius.net/bash-brace-expansion.html
#   - https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html
_exec() {
    # 作業用ディレクトリ作成
    basedirpath=/tmp/try-shellscript/brace_expansion/combination
    rm -rf "${basedirpath}"
    mkdir -p "${basedirpath}"

    echo '>> echo {a,b,c,d}{1,2,3}'
    echo {a,b,c,d}{1,2,3}
    echo '----------------------------'
}

_exec

実行すると以下のようになります。

gitpod /workspace/try-shellscript $ make run
ENTER EXAMPLE NAME: brace_expansion_combination

[INPUT ] brace_expansion_combination
[TARGET] brace_expansion_combination
[SCRIPT] basic/shell_expansions/brace_expansion/combination.sh

===== START [basic/shell_expansions/brace_expansion/combination.sh] =====
>> echo {a,b,c,d}{1,2,3}
a1 a2 a3 b1 b2 b3 c1 c2 c3 d1 d2 d3
----------------------------
===== END   [basic/shell_expansions/brace_expansion/combination.sh] =====

DONE

参考資料

www.putorius.net

www.gnu.org

devlights.hatenablog.com


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com