57891


すいません質問のタイトル及び本文の日本語が所々可笑しいかもしれません。

[code]

    FOR %%i IN (*.jpg) DO ( ~ )
    
[/code]

とした時、実際に存在する画像の名前が

[code]

    1.jpg,2.jpg...9.jpg,10.jpg
    
[/code]

この様な場合、処理の順番が

[code]

    1.jpg > 10.jpg > 2.jpg ... 9.jpg
    
[/code]

となってしまうのですがこれを名前順(表示)に処理することは可能ですか？


CC BY-SA 4.0
2019-09-04T11:41:39.423
57842
2019-09-06T03:09:47.693
31483
question
batch-file
BATのFORでリストを取得するときの並び順について


単純に`数値.txt`を数字順にソートするだけならば[teratail](https://teratail.com/questions/101231)の回答や後述のバッチファイル(`test.bat`)でソートできます。

しかしコードが複雑で流用しにくいものになりがちです。  
私もPowershellの使用をおすすめします。

### テスト用フォルダにサンプルファイルを書き出すスクリプト

回答の結果を例示するための下準備用Powershellスクリプトです。  
無視して構いません。

[code]

    # 下準備(ファイル作成)
    $numArr = @(1, 2, 4, 10, 200)
    foreach($num in $numArr) {
        $num >> "$num.txt"
        $num >> "prefix_$num.txt"
    }
    
[/code]

### test.bat

このバッチファイルでは数字をインクリメントしてファイルが存在する場合は表示することで疑似ソートしています。  
ファイルの桁数が大きいとそこそこ遅いです。

[code]

    @echo off
    setlocal enabledelayedexpansion
    
    rem ファイル名の最大値取得
    set max=0
    for %%f in (???.txt) do (
        if %%~nf gtr !max! set max=%%~nf
    )
    
    rem 数字をインクリメントしてヒットする場合は表示
    for /l %%i in (1, 1, %max%) do (
        set f=%%i.txt
        if exist !f! (echo !f!)
    )
    
[/code]

> 1.txt  
>  2.txt  
>  4.txt  
>  8.txt  
>  10.txt  
>  200.txt

### Powershell

`接頭辞+数字`を含むファイル名の有無に応じて、様々な方法で簡単にソートできるコードを例示します。

[code]

    # ファイル名が数字のみ抽出してソート
    ls | where BaseName -match "^\d+$" | sort { [int]$_.BaseName } | select Name
    
[/code]

> 1.txt  
>  2.txt  
>  4.txt  
>  8.txt  
>  10.txt  
>  200.txt
[code]

    # ファイル名から固定文字数削除(ここでは"prefix_"の7文字)して数字を切り出してソート
    ls | where { $_.BaseName.StartsWith("prefix_") } | sort { [int]$_.BaseName.SubString(7) } | select Name
    
[/code]

> prefix_1.txt  
>  prefix_2.txt  
>  prefix_4.txt  
>  prefix_8.txt  
>  prefix_10.txt  
>  prefix_200.txt
[code]

    # ファイル名から数字を正規表現で取り出してその次に普通のファイル名でソート
    ls | sort { [int]($_.Name -replace "\D", "") }, Name | select Name
    
[/code]

> 1.txt  
>  prefix_1.txt  
>  2.txt  
>  prefix_2.txt  
>  4.txt  
>  prefix_4.txt  
>  8.txt  
>  prefix_8.txt  
>  10.txt  
>  prefix_10.txt  
>  200.txt  
>  prefix_200.txt
[code]

    # 上記の逆に数字以外→数字順にソート
    ls | sort { $_.Name -replace "\d", "" }, { [int]($_.Name -replace "\D", "") } | select Name
    
[/code]

> 1.txt  
>  2.txt  
>  4.txt  
>  8.txt  
>  10.txt  
>  200.txt  
>  prefix_1.txt  
>  prefix_2.txt  
>  prefix_4.txt  
>  prefix_8.txt  
>  prefix_10.txt  
>  prefix_200.txt


CC BY-SA 4.0
2019-09-06T03:09:47.693
57891
2019-09-06T03:09:47.693
9820
57842
answer