Pythonのglob・osを用いた拡張子ごとのフォルダ振り分け

# 目次
[はじめに](#はじめに)
[作成した経緯](#作成した経緯)
[実行環境](#実行環境)
[正規表現を用いてフォルダにアクセスする方法](#正規表現を用いてフォルダにアクセスする方法)
[拡張子ありのファイル名の取得方法](#拡張子ありのファイル名の取得方法)
[ファイル名から拡張子を取得する方法](#ファイル名から拡張子を取得する方法)
[プログラムデータと結果・素材データの識別方法](#プログラムデータと結果・素材データの識別方法)
[フォルダの作成方法](#フォルダの作成方法)
[フォルダごとにデータを振り分ける方法](#フォルダごとにデータを振り分ける方法)
[ソースコード](#ソースコード)
[結果](#結果)
[まとめ](#まとめ)

# はじめに
今回は、[前回の記事](https://qiita.com/blueman/items/609e5a4be741ffa4983f)で振り分けたフォルダの中のデータを<font color="red">**拡張子から「結果・素材」フォルダと「ソースコード」フォルダにデータを振り分ける**</font>プログラムを紹介したいと思います。

--------

よろしければこちらもどうぞ!!

<details><summary>マイページについて</summary>

:::note info
主に<ins>**Pythonについての記事**</ins>を投稿してます!!
:::

[<font color="blue"><ins>**マイページはこちら**</ins></font>](https://qiita.com/blueman,"マイページ")

----------------------

</details>

<details><summary>X(Twitter)について</summary>

:::note info
<ins>**Qiitaの新着記事の通知**</ins>や<ins>**おススメの理工学書の紹介**</ins>をツイートしてます!!
:::
[<font color="blue"><ins>**X(Twitter)はこちら**</ins></font>](https://twitter.com/0ca00118726208m,"X(Twitter)")

-----------------------------

</details>

<details><summary>Zennについて</summary>

:::note info
主に<ins>**自分の書いたQiitaの記事の転載**</ins>と<ins>**Pythonを使っていて遭遇したエラーの対処法のような記事**</ins>を投稿していく予定です!!
:::
[<font color="blue"><ins>**Zennはこちら**</ins></font>](https://zenn.dev/blueman,"Zenn")

---------------------------

</details>

# 作成した経緯
[前回の記事](https://qiita.com/blueman/items/609e5a4be741ffa4983f)では大雑把に日付ごとで振り分けていたのですが、これだと<ins>**フォルダの中のデータが多いとプログラムデータと結果・素材データが分かりにくい**</ins>という問題が発生しました。
また、[GitHub](https://github.com/blueman3/Qiita_data_storage/tree/main/7_28)のディレクトリの構造上、<ins>**プログラムデータと結果・素材データを振り分けることでローカルにあるデータをGitHub上に送りやすくできる**</ins>ようにしました。

# 実行環境
実行環境は次の通りです。

<details><summary>実行環境</summary>

- **環境**
    - **`Windows 10`**
    - **`Python 3.10.5`**

:::note
<font color="red"> **`os`** </font>、<font color="red"> **`glob`** </font>は[<font color="red"><ins>**標準ライブラリ**</ins></font>](https://docs.python.org/ja/3/library/index.html)なので<font color="red">**特に気にしなくても大丈夫です!!**</font>
:::
</details>

**処理内容**と**モジュール・ライブラリ**の対応を分かりやすく表にすると次の通りです。
<details><summary>説明</summary>

| <font color="red">処理内容</font> | <font color="red">モジュール・ライブラリ</font> |
|:-:|:-:|
|**ファイル名の取得<br>ファイルの拡張子名の取得<br>フォルダの作成<br>ファイルの移動**|<font color="red"> **`os`** </font>|
|**正規表現を用いてフォルダに<br>アクセス**|<font color="red"> **`glob`** </font>|

</details>

# 正規表現を用いてフォルダにアクセスする方法
こちらのソース

https://note.nkmk.me/python-glob-usage/#0

を見ると、`Python`の<font color="red"> **`glob`** </font>というモジュールを使うことで[**ワイルドカード**](https://e-words.jp/w/%E3%83%AF%E3%82%A4%E3%83%AB%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89.html)**を使ってフォルダを指定できる**そうです。

このモジュールを使って<ins>フォルダの中にアクセス</ins>しました。

# 拡張子ありのファイル名の取得方法
[正規表現を用いてフォルダにアクセスする方法](#正規表現を用いてフォルダにアクセスする方法)でフォルダの中にアクセスできたので、次に<ins>**拡張子ありのファイル名**</ins>をこちらのソース

https://note.nkmk.me/python-os-basename-dirname-split-splitext/#_1

にある<font color="red"> **`os.path.basename()`** </font>を使って取得しました。

# ファイル名から拡張子を取得する方法
[拡張子ありのファイル名の取得方法](#拡張子ありのファイル名の取得方法)で拡張子付きのファイル名を取得できたので次にファイル名から拡張子のみを取り出す方法を調べました。

こちらのソース

https://aiacademy.jp/media/?p=1591

にある<font color="red"> **`os.path.splitext()`** </font>で拡張子を取得できることが分かりました。
このメソッドを使って、<ins>拡張子付きのファイル名から拡張子のみを取り出しました。</ins>

# プログラムデータと結果・素材データの識別方法
[ファイル名から拡張子を取得する方法](#ファイル名から拡張子を取得する方法)でファイルから拡張子を取得できました。
現状、**使っているプログラミング言語** は **`Python`** **のみ**なので`Python`のプログラムの拡張子である<font color="red">**`.py`**</font>**<ins>がファイルの拡張子かどうか**</ins>を<ins>**プログラムデータとそうではないデータの識別条件**</ins>としました。
また、フォルダを見ると拡張子が <font color="red">**`.JPG`**</font>・<font color="red">**`.jpg`**</font>・<font color="red">**`.png`**</font>・<font color="red">**`.mp4`**</font>のデータが<ins>結果・素材データ</ins>だったので<ins>**これらの拡張子がファイルの拡張子かどうか**</ins>を<ins>**結果・素材データとそうではないデータの識別条件**</ins>としました。

# フォルダの作成方法
前回の記事の[最終更新月日のフォルダの作成方法](https://qiita.com/blueman/items/609e5a4be741ffa4983f#%E6%9C%80%E7%B5%82%E6%9B%B4%E6%96%B0%E6%9C%88%E6%97%A5%E3%81%AE%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%81%AE%E4%BD%9C%E6%88%90%E6%96%B9%E6%B3%95)をもとに「結果・素材」フォルダと「ソースコード」フォルダを作成しました。

# フォルダごとにデータを振り分ける方法
前回の記事の[最終更新月日ごとでフォルダに振り分ける方法](https://qiita.com/blueman/items/609e5a4be741ffa4983f#%E6%9C%80%E7%B5%82%E6%9B%B4%E6%96%B0%E6%9C%88%E6%97%A5%E3%81%94%E3%81%A8%E3%81%A7%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%81%AB%E6%8C%AF%E3%82%8A%E5%88%86%E3%81%91%E3%82%8B%E6%96%B9%E6%B3%95)をもとに[プログラムデータと結果・素材データの識別方法](#プログラムデータと結果・素材データの識別方法)から識別したデータを[フォルダの作成方法](#フォルダの作成方法)で作成したフォルダに移動させました。

# ソースコード
下にソースコードを示します。おそらく[実行環境](#実行環境)で示した環境では動くはず。

<details><summary>ソースコード</summary>

```python:data_separate(ext).py
import glob                                                                                 #正規表現を用いてフォルダにアクセスするためにインポート
import os                                                                                   #ファイル名の取得・ファイルの拡張子名の取得・フォルダの作成・ファイルの移動のためにインポート

path_list=glob.glob('./python/*_*/*')                                                       #正規表現を用いて各フォルダにアクセス(「文字の真ん中に＿がある」フォルダにアクセス)

for i in path_list:                                                                         #それぞれの「文字の真ん中に＿がある」フォルダについて処理を実行
	file = os.path.basename(i)                                                              #フォルダ内の拡張子ありのファイル名を取得
	name = os.path.splitext(file)                                                           #ファイル名の.について文字を分割(これで拡張子を取得)

	if name[1] == ".JPG" or name[1] == ".jpg" or name[1] == ".png" or name[1]==".mp4":      #拡張子が「.JPG」、「.jpg」、「.png」、「.mp4」の場合に処理を実行
	                                                                                        #(画像ファイルか動画ファイルの場合)
		os.makedirs(os.path.dirname(i)+"/結果・素材",exist_ok=True)                         #拡張子が「.JPG」、「.jpg」、「.png」、「.mp4」であるファイルがあるフォルダ内に
		                                                                                    #「結果・素材」フォルダを(ない場合に)作成
		if(os.path.isfile(i)):                                                              #「文字の真ん中に＿がある」フォルダの直下に拡張子が「.JPG」、「.jpg」、「.png」、「.mp4」
	                                                                                        #であるファイルがある場合に処理を実行
			os.rename(i,os.path.dirname(i)+"/結果・素材/"+file)                             #「文字の真ん中に＿がある」フォルダの直下にある拡張子が「.JPG」、「.jpg」、「.png」、「.mp4」
			                                                                                #であるファイルを「結果・素材」フォルダ内に移動

	if name[1] == ".py":                                                                    #拡張子が「.py」の場合に処理を実行
		os.makedirs(os.path.dirname(i)+"/ソースコード",exist_ok=True)                       #拡張子が「.py」であるファイルがあるフォルダ内に「ソースコード」フォルダを(ない場合に)作成
		if(os.path.isfile(i)):                                                              #「文字の真ん中に＿がある」フォルダの直下に拡張子が「.py」であるファイルがある場合に処理を実行
			os.rename(i,os.path.dirname(i)+"/ソースコード/"+file)                           #「文字の真ん中に＿がある」フォルダの直下にある拡張子が「.py」であるファイルを「ソースコード」
			                                                                                #フォルダ内に移動
```

---------------------------

</details>

# 結果
下に結果を示します。

<details><summary>元のフォルダ内</summary>

![元のフォルダ内.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3198998/3a630536-6607-6be5-a642-36cad1e4b8a3.jpeg "元のフォルダ内")

----------------------------

</details>

元のフォルダ内は<ins>**プログラムデータと素材・結果データが混在**</ins>していて分かりにくくなっています。

こちらが処理実行後の同フォルダ内です。

<details><summary>処理実行後のフォルダ内</summary>

![処理実行後のフォルダ内.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3198998/b9644674-8a82-2a82-96ec-c5a41fc1bbe3.jpeg "処理実行後のフォルダ内")

----------------------------------

</details>

きちんと<ins>**「ソースコード」フォルダと「結果・素材」フォルダで振り分けられています。**</ins>

それぞれのフォルダ内は次の通りです。

<details><summary>「ソースコード」フォルダ内</summary>

![「ソースコード」フォルダ内.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3198998/e34b2e9f-a389-a3e8-6e2e-e2027548bf76.jpeg "「ソースコード」フォルダ内")

---------------------------------------

</details>

<details><summary>「結果・素材」フォルダ内</summary>

![変換後_フォルダ_3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3198998/1eee1987-624a-bb9a-0834-9ec1f08156c7.jpeg)

---------------------

</details>

きちんと<ins>**拡張子ごと**</ins>に振り分けられています。

# まとめ
今回は、<ins>**[前回の記事](https://qiita.com/blueman/items/609e5a4be741ffa4983f)のデータを拡張子ごとに振り分ける**</ins>ことを行いました。
この記事が実際に役に立つかどうかは分かりませんが、誰かの役に立ってくれると嬉しいです。
記事を執筆する余力があれば、<ins>次回も記事を投稿する予定</ins>です。
次回の予定としては、[**Twitter(X)のアンケート**](https://twitter.com/0ca00118726208m/status/1692153768840986941)でトップだった<font color="red"><ins>**動画像処理**</ins></font>から<font color="red"><ins>**画像の画素ごとの**</ins><font color="black">**補色**</font><ins>**で色変換を行いその結果と**</ins>[**ネガポジ反転**](https://pystyle.info/opencv-tone-transform/#outline__4)<ins>**から得られた結果とオリジナル画像を並べて表示させ補色による色変換とネガポジ反転の**</ins><font color="black">**画素値によるヒストグラム**</font><ins>**を表示させる**</ins></font>プログラムを作成できたのでそれに関する記事を投稿予定です。