Amazonで商品を見るセール会場へ

WindowsバッチとPowerShellでJSXファイルの連番を付け直してコピーする方法

JSXファイルの先頭の連番を振り直し、元ファイルを残して新しい名前のコピーを作ります。

BATからPowerShellを起動し、変更予定をプレビューしてから別フォルダーへコピーします。元ファイルを直接リネームするコードではありません。

目次

入力と出力の例

Windows練習用データとスクリプト(ZIP)

ZIPは空の練習フォルダーへ展開し、下の手順で指定するサブフォルダーを開いて使います。

01_Alpha.jsx、20_日本語 ! & [x].jsx、Zeta.jsxから、001_Alpha.jsx、002_日本語 ! & [x].jsx、003_Zeta.jsxを作ります。

出力ルートのmapping.csvには元の絶対パス、出力名、SHA256が記録されます。

対象はinputの直下にある.jsxだけで、元の名前をSort-Object Nameで並べてから001を付けます。既存番号を外した後の名前順や、Explorerの自然順ではありません。例えば10_が2_より先になることがあるため、プレビューの順番を確認してください。

数字とアンダースコアで始まる部分だけを除き、連番のない名前を切り落としません。

上限は999件で、SendToの選択順に番号を付けるコードではありません。

スポンサーリンク

変更予定を確認してコピーする

  1. ZIPのnumberフォルダーで、inputに練習用ファイルを用意する
  2. 下のPS1をnumber.ps1として保存するか、ZIPの同名ファイルを開く
  3. BATを実行し、SourceとRelativeOutputの予定だけを確認する
  4. 問題なければコマンドプロンプトで次の-Apply付きコマンドを実行する
  5. output/dataの内容とmapping.csvを確認し、inputが残っていることを確かめる

Windows PowerShell 5.1用のPS1はUTF-8(BOM付き)で保存します。

BATのRemoteSigned指定は起動したプロセスだけに適用し、ユーザーやPC全体の実行ポリシーは変更しません。

ダウンロードしたPS1が署名エラーになる場合は内容と出所を確認し、対象ファイルのプロパティからブロックを解除します。

組織のポリシーで実行できない場合は管理者へ確認し、ポリシーを回避して実行しないでください。

@echo off
setlocal DisableDelayedExpansion
powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File "%~dp0number.ps1"
exit /b %errorlevel%

BATはnumber.batとしてPS1と同じ場所へ保存し、プレビュー用の起動に使います。

powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File "number.ps1" -Apply

上の実行コマンドはnumber.ps1のあるフォルダーで使います。

param([string]$Source,
      [string]$Output,
      [switch]$Apply)
if (-not $Source) { $Source = Join-Path $PSScriptRoot 'input' }
if (-not $Output) { $Output = Join-Path $PSScriptRoot 'output' }

$ErrorActionPreference = 'Stop'
$rootItem = Get-Item -LiteralPath $Source
if (-not $rootItem.PSIsContainer) { throw 'Source must be a folder' }
$root = $rootItem.FullName.TrimEnd('\')
$out = [IO.Path]::GetFullPath($Output).TrimEnd('\')
if ($out -eq $root -or $out.StartsWith($root + '\', [StringComparison]::OrdinalIgnoreCase)) {
    throw 'Output must be outside Source'
}
if (Test-Path -LiteralPath $out) { throw 'Output already exists; choose a new name' }
$entries = @(Get-ChildItem -LiteralPath $root -Recurse -Force)
if (($rootItem.Attributes -band [IO.FileAttributes]::ReparsePoint) -or
    @($entries | Where-Object { $_.Attributes -band [IO.FileAttributes]::ReparsePoint }).Count) {
    throw 'Links/junctions are not supported'
}
$files = @($entries | Where-Object { -not $_.PSIsContainer })
$files = @($files | Where-Object { $_.DirectoryName -eq $root -and $_.Extension -ieq '.jsx' } | Sort-Object Name)
if (-not $files.Count) { throw 'No matching files' }
if ($files.Count -gt 999) { throw 'At most 999 files' }
$i = 0
$plan = @(foreach ($file in $files) {
    $i++
    $name = ('{0:D3}_' -f $i) + ($file.Name -replace '^\d+_', '')
    if ([string]::IsNullOrWhiteSpace($name) -or $name.IndexOfAny([IO.Path]::GetInvalidFileNameChars()) -ge 0 -or
        $name -match '[. ]$|^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|$)') { throw 'Invalid output name' }
    $relative = $name
    [pscustomobject]@{
        Source = $file.FullName
        RelativeOutput = $relative
        Destination = [IO.Path]::Combine($out, 'data', $relative)
        SHA256 = (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256).Hash
    }
})
if (@($plan | Group-Object Destination | Where-Object Count -gt 1).Count) {
    throw 'Duplicate destination names; nothing copied'
}
$plan | Format-List Source, RelativeOutput
if (-not $Apply) { Write-Host 'Preview only'; return }
[IO.Directory]::CreateDirectory($out) | Out-Null
$plan | Export-Csv -LiteralPath ([IO.Path]::Combine($out, 'mapping.csv')) -NoTypeInformation -Encoding UTF8
foreach ($row in $plan) {
    [IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($row.Destination)) | Out-Null
    [IO.File]::Copy($row.Source, $row.Destination, $false)
    if ((Get-FileHash -LiteralPath $row.Destination -Algorithm SHA256).Hash -ne $row.SHA256) {
        throw 'Hash mismatch; keep originals and inspect output'
    }
}
Write-Host ('Copied: ' + $plan.Count)

末尾へ文字を付ける場合

対象を同じ直下の.jsxとしたまま末尾へ文字を追加する場合は、上の$nameを代入する1行だけを次に置き換えます。

$name = $file.BaseName + '_サンプル' + $file.Extension

例:20_日本語 ! & [x].jsxは20_日本語 ! & [x]_サンプル.jsxになります。

失敗したときの確認と戻し方

Duplicate destination namesが出たら、同じ出力名になるファイルを一覧で確認し、入力のコピー側で名前を分けてからやり直します。

Output already existsが出たら既存の出力を上書きせず、-Outputで新しい絶対パスを指定します。

Sourceの内側を出力先にした場合や対象の.jsxがない場合は停止します。対象ファイルは直下だけですが、リンク・ジャンクションの検査は配下のサブフォルダーも含みます。SourceやOutputの親経路までは検査しないため、通常のローカルフォルダーを使い、実行中に別の処理で変更しないでください。

コピー中の権限エラーや容量不足、ハッシュ不一致では出力が一部だけ残るため、元データを使い続け、出力は未完成として確認します。

戻すときは変更していないinputを利用し、途中のoutputを制作データへ置き換えないでください。

この方法は通常ファイルの内容をコピーし、ACLや代替データストリームなどを含む完全なバックアップを作るものではありません。

2026年10月2日に実際のWindows PowerShell 5.1で、日本語・空白・!・&・角括弧を含む名前、プレビュー、コピー結果と元データの保持を確認しました。

Explorerのクリック操作とネットワーク共有上の処理は今回の検証に含みません。

コマンド仕様:Microsoft公式の実行ポリシー、File.Copyの上書き指定(2026年10月2日確認)。

従来の操作画面

以下は旧版の画面で、リスト入力や元の操作例の参考として残しています。

現在の手順は上のコードと入力・出力例を使い、CSVの拡張子変更や元ファイルの直接リネームは行いません。

旧版の操作画面(現在のコードと手順は本文を参照)

旧版の操作画面(現在のコードと手順は本文を参照)

業務効率化に役立つほかのツールは、以下のまとめ記事で紹介しています。

Windowsバッチファイルに関するほかの解説記事は、こちらをご覧ください。

連番を付け直す前の確認手順

実行前に、対象ファイルと出力される連番の順番を確認します。2026年10月2日にWindows PowerShell 5.1で確認した内容にもとづく目安です。この方法は、元のファイルを残したまま、新しい名前のコピーを作ります。

  1. まず、対象を確認する。対象は、inputの直下にある.jsxだけで、名前順に001から番号を付ける。上限は999件で、SendToの選択順に番号を付けるコードではない。
  2. 名前の先頭は、数字とアンダースコアで始まる部分だけを除き、連番のない名前を切り落とさない。例として、01_Alpha.jsxは001_Alpha.jsxに、Zeta.jsxは003_Zeta.jsxになる。
  3. ZIPのnumberフォルダーで、inputに練習用のファイルを用意し、SourceとRelativeOutputの予定だけを確認する。
  4. 問題がなければ、-Apply付きのコマンドを実行する。実行後は、output/dataの内容とmapping.csvを確認し、inputが残っていることを確かめる。
  5. 末尾に文字を付けたい場合は、$nameを代入する1行だけを置き換える。例として、20_日本語 ! & [x].jsxは、20_日本語 ! & [x]_サンプル.jsxになる。
  6. エラーが出たときは、元のデータを使い続け、出力は未完成として確認する。

実行ポリシーは、起動したプロセスだけに適用されます。ユーザーやPC全体の実行ポリシーは変更しません。

スポンサーリンク

まとめ

名前順と対象拡張子を固定し、連番を付けたコピーを出力して確認します。

よくある質問:連番のつけ直しで迷ったときのチェックリスト

元のファイルは変更されますか?

変更されません。元のファイルを残したまま、新しい名前のコピーを作ります。戻すときは、変更していないinputを使います。

連番は何件まで付けられますか?

上限は999件です。名前順に001から番号を付けます。SendToの選択順に番号を付けるコードではありません。

番号のない名前は、どうなりますか?

数字とアンダースコアで始まる部分だけを除き、連番のない名前は切り落としません。例として、Zeta.jsxは、003_Zeta.jsxになります。

同じ名前になるファイルがあるときは?

「Duplicate destination names」が出たら、同じ出力名になるファイルを一覧で確認し、入力のコピー側で名前を分けてから、やり直します。

「Output already exists」と出たら?

既存の出力を上書きせず、-Outputで新しい絶対パスを指定します。

コピーの途中でエラーが出たときは?

権限エラーや容量不足、ハッシュの不一致では、出力が一部だけ残ります。元のデータを使い続け、出力は未完成として確認してください。途中のoutputを、制作データへ置き換えないでください。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

仕事効率化のおすすめ書籍

仕事用PCの選び方

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次