[linux, mkdir] 連番のディレクトリにサブディレクトリを作成する方法

記事内に広告が含まれています。

000 から 10 までの番号のディレクトリの中で、存在するディレクトリにのみ subdir ディレクトリを作成する方法を紹介します。

状況設定

仕事で以下のようなケースにでくわしました。

3桁の数字で構成されるディレクトリが多数あり、その全ての下にsubdirというディレクトリを作成してください。ただし、数字は001~100まであり、基本連番ですが、中には歯抜けの数字も存在します。その場合、歯抜けの部分は作成しないでスキップしてください。

例として以下の状況を想定します。001は存在しているため、001/subdir は作成するが、 002は存在しないため002を作らずスキップする という状況です。

// 002は存在していないため、subdirを作成しない
.
├── 000
├── 001
├── 003
└── 010

ディレクトリを作るコマンドである mkdir には正規表現を使うためのオプションが存在しないため、別のコマンドと組み合わせて使う必要があります。

方法1: for ループと条件分岐を使う方法

結論をワンライナーで書くと、

for i in $(seq -w 0 100); do [ -d "$i" ] && mkdir -p "$i/subdir"; done
  • for i in $(seq -w 0 100):
    • seq コマンドは、指定された範囲の数値を生成します。-w オプションを使うと、ゼロパディングされた出力が得られます。つまり、000 から 100 までの3桁の数値が生成されます。
  • [ -d "$i" ]:
    • 条件分岐のテストコマンドです。-d オプションは、指定されたパスがディレクトリであるかどうかを確認します。
  • && mkdir -p "$i/subdir":
    • && は前のコマンドが成功した場合にのみ次のコマンドを実行するオペレーターです。ここでは、指定されたディレクトリが存在する場合にのみ mkdir -p コマンドが実行され、subdir ディレクトリが作成されます。

方法 2: find コマンドを使用

find . -maxdepth 1 -type d -regex '\./[0-9]\{3\}' -exec mkdir -p {}/subdir \;
  • find . -maxdepth 1 -type d:
    • find コマンドは、指定されたパス(この場合は現在のディレクトリ .)内で検索を行います。-maxdepth 1 は検索の深さを1に制限し、現在のディレクトリの直下のみを検索対象とします。-type d はディレクトリのみを対象とするオプションです。
  • -regex '\./[0-9]\{3\}':
    • -regex オプションは、正規表現を使用して一致するパスを検索します。'\./[0-9]\{3\}' は現在のディレクトリ内の3桁の数字からなるディレクトリを指定しています。[0-9]\{3\} は任意の3桁の数字を表します。
  • -exec mkdir -p {}/subdir \;:
    • -exec オプションは、検索結果に対して指定したコマンドを実行します。{} は検索結果のディレクトリに置き換えられます。mkdir -p {}/subdir は各ディレクトリに対して subdir ディレクトリを作成するコマンドです。

方法 3: xargs コマンドを使用

seq -w 0 100 | xargs -I {} bash -c '[ -d "{}" ] && mkdir -p "{}"/subdir'
  • seq -w 0 100:
    • seq コマンドで 000 から 100 までの数値を生成します。
  • xargs -I {} bash -c '[ -d "{}" ] && mkdir -p "{}"/subdir':
    • xargs コマンドは、標準入力から読み取ったデータを引数として他のコマンドに渡します。-I {} はプレースホルダーとして {} を使用し、各入力行ごとにコマンドを実行します。
    • bash -c '[ -d "{}" ] && mkdir -p "{}"/subdir' は、各数値についてディレクトリの存在をチェックし、存在する場合にのみ subdir ディレクトリを作成します。
    • bash -c の-cオプションは、後続の”で囲まれた文字列をコマンドとして実行します。

方法 4: while ループを使用

i=0; while [ $i -le 100 ]; do printf -v dir "%03d" $i; [ -d "$dir" ] && mkdir -p "$dir/subdir"; i=$((i+1)); done
  • i=0:
    • カウンタ変数 i を初期化します。
  • while [ $i -le 100 ]; do ... done:
    • while ループは、カウンタ変数 i100 以下の間、ループを実行します。
  • printf -v dir "%03d" $i:
    • printf コマンドを使用して、カウンタ変数 i をゼロパディングされた3桁の文字列に変換し、変数 dir に格納します。
  • [ -d "$dir" ] && mkdir -p "$dir/subdir":
    • ディレクトリの存在を確認し、存在する場合にのみ subdir ディレクトリを作成します。
  • i=$((i+1)):
    • カウンタ変数 i をインクリメントします。

結論

mkdirに正規表現を使うオプションが存在しないため、今回のようなケースでは複数のコマンドを組み合わせてコードを書き必要があります。

このコードを応用すると、今度はsubdirの削除もすぐに書くことが可能です。その方法は以下の記事をご参照ください。

Linux
スポンサーリンク