以下のように、1 つのフォルダーに多数の Excel ファイルがあります。
+----------------------+
| 01012019_LOC001.xlsx |
| 01012019_LOC002.xlsx |
| 01012019_LOC003.xlsx |
| 02012019_LOC001.xlsx |
| 02012019_LOC002.xlsx |
| 02012019_LOC003.xlsx |
| 03012019_LOC001.xlsx |
| 03012019_LOC002.xlsx |
| 03012019_LOC003.xlsx |
+----------------------+
日付と場所の組み合わせ構造DDMMYYYY_LOCXXX
これらのファイルを、以下の構造に似た作成されたそれぞれのフォルダーに移動したいと思います。
MAIN_FOLDER
|
|-LOC001
|-01012019
|-02012019
|-03012019
|
|-LOC002
|-01012019
|-02012019
|-03012019
|
|-LOC003
|-01012019
|-02012019
|-03012019
|
一度に 1 つずつ転送できますfor /r %d in (01012019_LOC001.xlsx) do move "%d" "C:MAIN_FOLDER\LOC001\01012019\"
。
しかし、私はもっと動的な解決策を探しています。したがって、解決策を見つけるために私を導いてください。
PS注:- PowerShell の回答でも十分です。
答え1
このためには、遅延展開を使用してファイルをループする必要があります。サブフォルダーも取得したい場合を除き、再帰的な/r
フラグは使用しないでくださいfor
。主な問題は、ファイル名を分割することです。各半分は別々の情報であるためです。次のようになります。
@echo off
set "dir=C:\Your\Excel\File\Directory"
set "des=C:\MAIN_FOLDER"
setlocal enabledelayedexpansion
for %%A in (%dir%\*.xlsx) do (
set "file=%%~nA"
if not exist "%des%\!file:~-6!" md "%des%\!file:~-6!"
if not exist "%des%\!file:~-6!\!file:~0,8!.xlsx" move /y "%dir%\%%~nxA" "%des%\!file:~-6!\!file:~0,8!.xlsx"
)
これはバッチ ソリューションなので、メモ帳にコピーして貼り付け、.bat
ではなくとして保存するだけです.txt
。
まず、変数をdir
(ディレクトリ; Excel ファイルが現在配置されている場所) とdes
(移動先; フォルダーを作成してファイルを移動する場所) に設定しました。これらの値は、環境を反映するように編集する必要があります。他の操作を行う前に、setlocal enabledelayedexpansion
ループの反復ごとに値が変わる変数を操作しているため、 を使用します。 は、for
ディレクトリの最上位フォルダーにあるすべての Excel ファイルをループし、それらをパラメーター に割り当てます%%A
。ループ内に入ると、 という変数を に設定しますfile
。%%~nA
これは、パラメーター%%A
をファイル名だけに縮小したものです。1 つのif
ステートメントを使用して、そのファイルのフォルダーが既に存在するかどうかを確認します。存在しない場合は、 を使用してフォルダーを作成しmd
、別のif
ステートメントを使用して、現在参照しているファイルが確認/作成したフォルダーに既に存在するかどうかを確認します。存在しない場合は、 を使用してファイルをフォルダーに移動しmove
、 を使用して確認プロンプトを抑制します/y
(/y
ステートメントで開始するため、 は実際には必要ありませんif
が、個人的にはこれがベスト プラクティスです)。move コマンドには名前変更が組み込まれているため、それを使用して、必要な命名スキームに従います。
ここでのチープな部分は変数の部分文字列です。日付と場所は文字数が決まっているため、それらの文字を数えて必要に応じて抽出します。
!file:~-6!
つまり、最後の 6 文字 (LOC 情報) を取得し、!file:~0,8!
最初の 8 文字 (日付情報) を取得します。他に注目すべき点は、遅延展開を使用するループ内で感嘆符を使用することです (感嘆符は変化する変数であるため)。静的変数 (dir
およびdes
) では、パーセント記号はどこでも問題ありません。
これで望みどおりの結果が得られるか、少なくとも正しい方向に進むことができることを願っています。
答え2
完全を期すために、ここにパワーシェルバージョン:
$Source = 'C:\Source'
$Dest = 'C:\Destination'
Get-ChildItem $source -filter *.xls | foreach{
$FolderName = $_.Basename.Split('_')[1]
If (!(Test-Path "$Dest\$FolderName")) {
New-Item -Path $Dest -Name $FolderName -ItemType Directory | out-null
}
Move-Item $_.FullName "$Dest\$FolderName"
}
私は場所###文字列をアンダースコアで分割すると、それ自体は2要素の文字列配列を返します。1添え字は2番目の要素を参照します。テストパス失敗した場合は、フォルダーを作成し、戻り値をパイプでアウトヌル画面表示を避けるため、アイテムの移動まさにその名の通りです! :)