正規表現を使ってファイル名を修正し、指定したフォルダ内に格納する方法を教示ください。

例えば、

Flexible Renamerの詳細情報 : Vector ソフトを探す!
http://www.vector.co.jp/soft/winnt/util/se131133.html

のようなソフトで実現できれば良いですが、
難しい場合にはshもしくはbatで実現する方法を教えて下さい。

【対象ファイル名】
XXXXXX(数字6桁)_sub3.jpg
G15H-37-XXXXXX(数字6桁)-65A.JPG
上記の2パターン

【格納フォルダ名】
/XXXXXX(数字6桁)/連番.jpg


回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2015/06/30 20:30:04
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。
id:masakiplus

プラットホームはWindowsです。

シェルであればcygwinを使う想定です。

ベストアンサー

id:siachan No.2

回答回数91ベストアンサー獲得回数23

ポイント150pt

f:id:siachan:20150628150111:image
Flexible Renamerを使った方法ですが、検索の欄に

^(?:(\d{6})_sub3|G15H-37-(\d{6})-65A)\.jpg

と入力し、置換の欄に

.\\\1\2\\???.jpg

と入力します。ここでは連番を三桁としたので ??? にしましたが、四桁なら ???? にします。

あとは実行する動作を「別フォルダに移動&リネーム」にして「移動」ボタンを押すと移動先のルートフォルダを聞いてくるので選択するだけです。


ちなみに、はっきり言って実用的ではありませんが、バッチファイルだとこんな感じでしょうか。

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /f %%F in ('dir/b/s *.jpg^|findstr/i ^^G15H-37-[0-9]*-65A\.jpg') do (
   echo %%F
   set FILE=%%F
   set NUM=!FILE:~-14,6!
   if not exist .\!NUM!\nul md !NUM!
   set COUNT=1
   for %%C in (.\!NUM!\*.jpg) do set /a COUNT=COUNT+1
   move %%F .\!NUM!\!COUNT!.jpg
)
for /f %%F in ('dir/b/s *.jpg^|findstr/i ^^[0-9]*_sub3\.jpg') do (
   echo %%F
   set FILE=%%F
   set NUM=!FILE:~-15,6!
   if not exist .\!NUM!\nul md !NUM!
   set COUNT=1
   for %%C in (.\!NUM!\*.jpg) do set /a COUNT=COUNT+1
   move %%F .\!NUM!\!COUNT!.jpg
)

ENDLOCAL

かなり無理矢理な感じがしますね。

id:Bookmarker

Flexible Renamerを使った方法は、ほぼ同じものを私も思いついたのですが、「連番」が全体の通し番号になってしまうので、質問者さんの期待と違うのではないかと思いました。
No.1の回答のように、コピー先の各フォルダ毎の通し番号を期待しているのではないかと思ったのですが、どちらを期待しているのですかね。

^(?:(\d{6})_sub3|G15H-37-(\d{6})-65A)\.jpg$
\1\2/?.jpg
2015/06/28 17:18:32
id:siachan

そうなるとちょっとFlexible Renameを使った方法は思いつかないので、バッチファイルの方を修正しました。
あ、サブフォルダ内も検索対象にしてしまってるんですが、必要ないなら dir の後の /s は消して下さい。

2015/06/28 18:09:26

その他の回答1件)

id:Mook No.1

回答回数1314ベストアンサー獲得回数393

ポイント150pt

BAT では正規表現が使えないので、VBS か PowerShell でどうでしょうか。
下記 VBS の例ですが、ファイルの移動かコピーか判別付かなかったので、コピーにしています。

Option Explicit

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim cPath
cPath = Replace(WScript.ScriptFullName,WScript.ScriptName,"")

Dim pt, f, dPath, ret
For Each f in fso.GetFolder(cPath).Files
    For Each pt In Array( "^(\d{6})_sub3.jpg", "^G15H-37-(\d{6})-65A.jpg" )
        ret = RegExpTest( pt, f.Name)
        If ret <> -1 Then
            dPath = cPath & "\" & ret
            If fso.FolderExists( dPath ) = False Then fso.CreateFolder dPath
            fso.CopyFile f.Path, dPath & "\" & (fso.GetFolder(dPath).Files.Count + 1) & ".jpg"
        End If
    Next
Next

'// 正規表現でチェック
Function RegExpTest(patrn, strng)
   Dim regEx, Match
   Set regEx = New RegExp
   regEx.Pattern = patrn
   regEx.IgnoreCase = True
   regEx.Global = True
   If regEx.Test(strng) Then
       Set Match = regEx.Execute(strng)
       RegExpTest = Match.Item(0).SubMatches(0)
   Else
       RegExpTest = -1
   End If
End Function

PowerShell であればこんな感じで(シンタックス・ハイライトに PowerShell がない…)。

Get-ChildItem "D:\Data" | Where { $_ -match "^\d{6}_sub3.jpg" -or $_ -match "^G15H-37-\d{6}-65A.JPG"} | %{
    if( $_ -match "^\d{6}_sub3.jpg" ) { $sp = 0 } else { $sp = 8 }
    $numFolder = ($_.DirectoryName + "\" + [string]($_.Name).Substring($sp,6))
    If ( ( Test-Path $numFolder -PathType Container ) -eq $False ) { New-Item $numFolder -Type directory }
    Copy-Item -Path $_.FullName  -Destination ($numFolder + "\" + ( (Get-ChildItem $numFolder | Measure-Object).Count + 1 )+ ".jpg" ) }
id:siachan No.2

回答回数91ベストアンサー獲得回数23ここでベストアンサー

ポイント150pt

f:id:siachan:20150628150111:image
Flexible Renamerを使った方法ですが、検索の欄に

^(?:(\d{6})_sub3|G15H-37-(\d{6})-65A)\.jpg

と入力し、置換の欄に

.\\\1\2\\???.jpg

と入力します。ここでは連番を三桁としたので ??? にしましたが、四桁なら ???? にします。

あとは実行する動作を「別フォルダに移動&リネーム」にして「移動」ボタンを押すと移動先のルートフォルダを聞いてくるので選択するだけです。


ちなみに、はっきり言って実用的ではありませんが、バッチファイルだとこんな感じでしょうか。

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /f %%F in ('dir/b/s *.jpg^|findstr/i ^^G15H-37-[0-9]*-65A\.jpg') do (
   echo %%F
   set FILE=%%F
   set NUM=!FILE:~-14,6!
   if not exist .\!NUM!\nul md !NUM!
   set COUNT=1
   for %%C in (.\!NUM!\*.jpg) do set /a COUNT=COUNT+1
   move %%F .\!NUM!\!COUNT!.jpg
)
for /f %%F in ('dir/b/s *.jpg^|findstr/i ^^[0-9]*_sub3\.jpg') do (
   echo %%F
   set FILE=%%F
   set NUM=!FILE:~-15,6!
   if not exist .\!NUM!\nul md !NUM!
   set COUNT=1
   for %%C in (.\!NUM!\*.jpg) do set /a COUNT=COUNT+1
   move %%F .\!NUM!\!COUNT!.jpg
)

ENDLOCAL

かなり無理矢理な感じがしますね。

id:Bookmarker

Flexible Renamerを使った方法は、ほぼ同じものを私も思いついたのですが、「連番」が全体の通し番号になってしまうので、質問者さんの期待と違うのではないかと思いました。
No.1の回答のように、コピー先の各フォルダ毎の通し番号を期待しているのではないかと思ったのですが、どちらを期待しているのですかね。

^(?:(\d{6})_sub3|G15H-37-(\d{6})-65A)\.jpg$
\1\2/?.jpg
2015/06/28 17:18:32
id:siachan

そうなるとちょっとFlexible Renameを使った方法は思いつかないので、バッチファイルの方を修正しました。
あ、サブフォルダ内も検索対象にしてしまってるんですが、必要ないなら dir の後の /s は消して下さい。

2015/06/28 18:09:26
id:masakiplus

言葉足らずでした。すいません。

連番はフォルダ単位での連番を想定しています

  • id:TransFreeBSD
    Windowsでしょうか?
    grepやsedが使えるならそれ使うと良いと思いますが、
    dirで名前取ってエディタで置換する手はどうでしょう?
  • id:TransFreeBSD
    言葉足らずでした。多分。
    dirで名前取ってエディタで置換してbatファイルを作る手はどうでしょう?
    です。
    置換で全てのファイルを
    mkdir XXXXXX
    move XXXXXX_sub3.jpg XXXXXX/連番.jpg
    に変えてバッチファイルにするって意味です。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません