我有一个开膛手,可以从reddit等网站下载gif,webms,jpg,mp4和png文件。
我大约有25,000个文件和1,500个子文件夹。
当前,我的“原始”文件夹就像是混合的
└───UNSORTED
└───RAW
├───reddit_sub_funnycatswithdog
│ ├───funcatdog.jpg
│ ├───fundogcat.png
│ ├───funnycatswithdog_983j331_cutecattries-to_.gif
│ ├───and 500 more
├───reddit_sub_funnydogs
│ ├───randomcutedog.jpg
│ ├───randomdogs.png
│ ├───dograndomfun.webm
│ ├───and 500 more
你明白了。
现在,我有一批可以像这样过滤/排序
└───Sorted
├───GIF FOLDER
│ ├───reddit_sub_funnycatswithdog
│ │ ├───funnycatswithdog_983j331_cutecattries-to_.gif
│ │ └───and 100 more
│ ├───reddit_sub_funnydogs
│ │ ├───funnydogs_fdsljdsd9s_kiotdawg_123.gif
│ │ └───and 100 more
│ ├───reddit_sub_imoutofrandomnames
│ │ ├───imoutofrandomnames_92382j38du8yu_socute.gif
│ │ ├───and 100 more
│ └───reddit_sub_randommemes
│ ├───randommemes_023093x23_uploadedtitle.gif
│ └───and 100 more
├───JPG
│ ├───reddit_sub_funnycatswithdog
│ │ ├───reddit_sub_funnycatswithdog_983j331_cuteries-to_eatdog.JPG
│ │ └───and 100 more
│ ├───reddit_sub_funnydogs
│ │ ├───reddit_sub_funnydogs_fdsljdsd9s_kiotdawg_123.JPG
│ │ └───and 100 more
│ ├───reddit_sub_imoutofrandomnames
│ │ ├───imoutofrandomnames_92382j38du8yu_socute.JPG
│ │ └───and 100 more
│ ├───reddit_sub_randommemes
│ │ ├───randommemes_023093x23_uploadedtitle.JPG
│ │ └───and 100 more
问题1:记录并排除
问题是,如果该文件从未由批处理文件处理,我只想尝试复制。日志排除只是我目前所看到的解决方案,但是欢迎任何使用。
问题2:检查类型并相应地移动
我还想知道我是否可以稍微清理一下代码以使其更好。 我认为现在它会扫描每个文件5次,以查找5种不同类型的文件,然后将其移动。
有没有办法只做一次?检查类型,如果gif移动到gif,如果jpg移动到jpg等
这是我到目前为止所拥有的。 (没有日志记录或其他内容,因为我不确定格式或需要正确记录的内容)
Echo off
SETLOCAL EnableDelayedExpansion
set RAW=D:\RIP\RAW
set GIF=D:\RIP\OneDrive\Sek\GIF
set PNG=D:\RIP\OneDrive\Sek\png
set MP4=D:\RIP\OneDrive\Sek\MP4
set JPG=D:\RIP\OneDrive\Sek\JPG
set WEBM=D:\RIP\webm
cd d:
Cd %RAW%
REM FOR ALL FOLDERS, DO GET IN
for /D %%u in (*) do (
cd "%%u"
REM ONCE IN, FOR ALL THE FILES IN THE FOLDER, CHECK IF GIF, THEN DO
for /r %%p in (*.gif) do (
echo n|xcopy /C /i "%%p" "%GIF%\%%u\%%~nxp*"
)
REM ONCE IN, FOR ALL THE FILES IN THE FOLDER, CHECK IF JPG, THEN DO
for /r %%p in (*.JPG) do (
echo n|xcopy /C /i "%%p" "%JPG%\%%u\%%~nxp*"
)
REM ONCE IN, FOR ALL THE FILES IN THE FOLDER, CHECK IF MP4, THEN DO
for /r %%p in (*.MP4) do (
echo n|xcopy /C /i "%%p" "%MP4%\%%u\%%~nxp*"
)
REM ONCE IN, FOR ALL THE FILES IN THE FOLDER, CHECK IF WEBM, THEN DO
for /r %%p in (*.WEBM) do (
echo n|xcopy /C /i "%%p" "%WEBM%\%%u\%%~nxp*"
)
REM ONCE IN, FOR ALL THE FILES IN THE FOLDER, CHECK IF PNG, THEN DO
for /r %%p in (*.PNG) do (
echo n|xcopy /C /i "%%p" "%PNG%\%%u\%%~nxp*"
)
rem Go back one level up to %RAW% to process next %%u
cd ..
)
我尝试过:
for /r %%p in (*) do (
if %%~xp == .GIF (
echo n|xcopy /C /i "%%p" "%GIF%\%%u\%%~nxp*"
)
for /r %%p in (*) do (
if %%~xp == .JPG (
echo n|xcopy /C /i "%%p" "%GIF%\%%u\%%~nxp*"
)
但是它只会在所有目录中复制相同的文件,如下所示:
└───Sorted
├───GIF FOLDER
│ ├───reddit_sub_funnycatswithdog
│ │ ├───funnycatswithdog_983j331_cutecattries-to_.gif
│ │ ├───and 100 more
│ ├───reddit_sub_funnydogs
│ │ ├───funnycatswithdog_983j331_cutecattries-to_.gif
│ │ ├───and 100 more
│ ├───reddit_sub_imoutofrandomnames
│ │ ├───funnycatswithdog_983j331_cutecattries-to_.gif
├───JPG FOLDER
│ ├───reddit_sub_funnycatswithdog
│ │ ├───funnycatswithdog_983j331_cutecattries-to_.JPG
│ │ ├───and 100 more
│ ├───reddit_sub_funnydogs
│ │ ├───funnycatswithdog_983j331_cutecattries-to_.JPG
│ │ ├───and 100 more
│ ├───reddit_sub_imoutofrandomnames
│ │ ├───funnycatswithdog_983j331_cutecattries-to_.JPG
我希望:
答案 0 :(得分:0)
在我看来,这听起来像是XY Problem。如果我是您,我会退后一步,重新考虑整个方法。
让我们分析使脚本运行缓慢的原因,而不是实施日志记录功能以排除已复制的项目。原因和相应的对策:
Overwrite ... (Yes/No/All)?
提示符;管道会为双方创建新的cmd
实例,这需要一些时间。您可以使用if exist "<target>" copy "<source>" "<target>"
通过检查目标文件是否已经存在来避免它们。或者甚至更好的是,您可以让xcopy
使用xcopy /D /Y "<source>" "<target>"
检查自上次复制以来源文件是否已更改。因此,这是一个可能的解决方案(不具有日志记录功能),它应该比您的方法明显更快-请参阅说明其工作原理的所有说明(rem
):
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=UNSORTED\RAW" & rem // (this path must not contain `=`, `!` or `^`)
set "_TARGET=SORTED" & rem // (this path may contain all valid characters)
rem /* Define a pseudo-array with file extensions as indexes, including the preceding `.`,
rem and directory names as values; this allows to define the same directory for several
rem file extensions: */
set "$DIRS[.gif]=GIF"
set "$DIRS[.jpeg]=JPG"
set "$DIRS[.jpg]=JPG"
set "$DIRS[.mp4]=MP4"
set "$DIRS[.png]=PNG"
set "$DIRS[.webm]=WEBM"
rem // Use `for` loop that iterates once to resolve target path:
for /D %%D in ("%_TARGET%") do set "ROOT=%%~fD"
rem // Change into source directory:
pushd "%_SOURCE%" && (
rem // Use `for` loop that iterates once to resolve the source path:
for /D %%D in (".") do (
rem // Build list of file patterns that matches all the specified file extensions:
set "EXTS="
for /F "tokens=2 delims=[]" %%X in ('set $DIRS[') do call set "EXTS=%%EXTS%% *%%X"
rem // Find matching files in the source directory tree and iterate through them:
for /F "delims=" %%F in ('dir /B /S /A:-D %%EXTS%%') do (
rem // Store the path of the currently iterated file:
set "FILE=%%F"
setlocal EnableDelayedExpansion
rem /* Build the destination file path by concatenating the resolved target
rem directory, the directory namd associated with the current file
rem extension and the file path relative to the source directory (which
rem is the full file path with the resolved source path removed): */
set "DEST=!ROOT!\!$DIRS[%%~xF]!\!FILE:*%%~fD\=!"
rem // Create destination directory, suppress error message if already done:
2> nul md "!DEST!\.."
rem // Copy the current file to the target location, except when already done:
if exist "!DEST!" (
> nul xcopy /Y /D "!FILE!" "!DEST!"
) else (
> nul copy "!FILE!" "!DEST!"
)
endlocal
)
)
rem // Return from source directory:
popd
)
endlocal
exit /B