有没有办法制作日志并将该日志从批处理的后续运行中排除

时间:2019-02-05 19:32:51

标签: batch-file cmd

我有一个开膛手,可以从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

我希望:

  1. 一种仅需每次尝试一次即可复制/复制唯一文件的方式,无论我何时运行批处理
  2. 因为它们真的很慢,所以对其进行排序的快捷方法。

1 个答案:

答案 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