LoginSignup
0
0

More than 1 year has passed since last update.

globとコマンドラインのワイルドカード(*)でハマった件

Last updated at Posted at 2023-01-10

発生した問題

データセットを作成する時は大体拡張子別にディレクトリを分けているのですが,今回はたまたま 2 種類の拡張子を持つファイルが 1 つのディレクトリに入ってしまっていたので,Python のコード内でこれらを分けて取得する必要がありました.
しかし,この取得の段階で glob コマンドがなぜかうまく動きませんでした
本記事では発生した事項,解決策,結論について述べたいと思います.

以下に今回のディレクトリ&ファイル構造を示します.

dir_structure
.
├── glob.py
└── dataset_dir
    ├── 001.txt
    ├── 002.txt
    ├── 003.txt
    ├── ...
    ├── 100.txt
    ├── 001.png
    ├── 002.png
    ├── 003.png
    ├── ...
    └── 100.png

このディレクトリ構造に対して,以下のコードを用いて.txtおよび.pngファイルの path を格納したリストを作成します.

glob.py
txt_path = glob.glob(sys.argv[1])
png_path = glob.glob(sys.argv[2])
print(txt_path, len(txt_path))
print(png_path, len(png_path))
command line
python glob.py ./dataset_dir/*.txt ./dataset_dir/*.png 

しかし,このプログラムの出力は以下の通りでした.
./dataset_dir/001.png 1
./dataset_dir/002.png 1
なぜこのようなことが発生したのでしょうか?

解決策

私の脳内の理解では以下のようなものでした.

  1. python glob.py ./dataset_dir/*.txt ./dataset_dir/*.pngが実行される
  2. プログラム内で与えられた引数が str 変数としてtxt_path = glob.glob(./dataset_dir/*.txt)およびtxt_path = glob.glob(./dataset_dir/*.png)のように渡される.
  3. glob 関数によってディレクトリ内のファイル一覧を取得する.

しかし,この2が間違っていました.
そもそも,Python の引数としてワイルドカードを利用すると,str としてそのまま受け取られるのではなく,その段階でディレクトリ内全てのファイルを指定したことになるので,実行段階のpython glob.py ./dataset_dir/*.txt ./dataset_dir/*.pngとは,len(sys.argv) = 3 ではなく,len(sys.argv) = 101 (script1 + txt50 + png50) という時点でミスを犯していたことになります.

ですので,コマンドライン上でワイルドカードを利用しないというのが正解なようです.
よって,以下のようにプログラムを変更することが正しいです.

glob.py
txt_path = glob.glob(sys.argv[1] + '/*.txt')
png_path = glob.glob(sys.argv[2] + '/*.png')
print(txt_path, len(txt_path))
print(png_path, len(png_path))
command line
python glob.py ./dataset_dir/

結論

コマンドライン上でワイルドカードを用いると即効魔法が発動するので,sys.argv に吸収される時には既にデータはワイルドに獲得されている.

追記

@yoshi389111 さんよりコメントをいただきました.(2023/01/11 確認)
ご提案いただいた内容は「そもそもコマンドライン上で実行する時にはクォーテーション(またはダブルクォーテーション)で囲うことでワイルドカードを非アクティブ化できる」というものでした.確かに!その手がありました!!

command line
python glob.py './dataset_dir/*.txt' './dataset_dir/*.png' 
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0