batch file that remembers what was copied [closed]

人盡茶涼 提交于 2019-12-13 08:45:21

问题


This was the initial question which I need to be "extended" Creating folder from file, copy initial file into folder and add prefix

This is the output batch

for /f "tokens=*" %%A in ('dir /b *.mp4') do (
    md "%%~nA"
    copy "%%~fA" "%%~nA\prefix_%%~nxA"
)

(if there is a .mp4, create a folder with that files name and copy the .mp4 into that folder)

Now that batch file should "remember" what folder was created so it wont restart the same operation every time when the newly created folder is deleted. I was thinking like "write the name into a .txt then perform rest from above bat" every new batch task could check if the name exists. if no = copy, if yes = do nothing.


回答1:


The answer written by Aacini is good and was voted up by me, but could result in wrong MP4 file processing under certain conditions.

The conditions on which wrong processing occurs are:

  1. The *.mp4 files are stored on a FAT, FAT32 or exFAT instead of an NTFS drive.

    On FAT drives as often used on SD cards and USB sticks the file system returns files matching a pattern according to file allocation table entry (usually oldest first) and not sorted alphabetically according to name as NTFS file system always does.

  2. There are MP4 files which names are substrings of other MP4 files with longer names.

    For example there is a file Test1.mp4 which was created first on a FAT32 drive (first in file allocation table) and also a file Test.mp4 which was created later and is therefore newer (second in file allocation table).

The usually working code written by Aacini results now with older Test1.mp4 and newer Test.mp4 on FAT32 drive in

  • creating directory Test1,
  • copying Test1.mp4 into directory Test1,
  • writing Test1 into the text file,
  • skipping processing for Test.mp4 because string Test already found in text file as being a substring of Test1.

Following enhancements could be made to avoid this unwanted behavior under these conditions:

  1. Use parameter /ON on command DIR to get the list sorted alphabetically by name as on NTFS drives.

  2. Make sure not finding in text file the current file/directory name within a longer file/directory name.

And file/directory names are case insensitive on Windows which should be also taken into account on searching in text file using option /I.

The first solution uses also command FIND which does not have an option to match entire lines only. The file/directory name is written therefore with surrounding : into the text file and also searched with surrounding colons. A colon can't be in name of a file or directory making it a good start/end delimiter.

@echo off

if not exist FoldersCreated.txt cd . > FoldersCreated.txt

for /F "tokens=*" %%A in ('dir /A-D /B /ON *.mp4') do (
    %SystemRoot%\System32\find.exe /I ":%%~nA:" FoldersCreated.txt >NUL
    if errorlevel 1 (
        md "%%~nA"
        copy "%%~fA" "%%~nA\prefix_%%~nxA"
        echo :%%~nA:>>FoldersCreated.txt
    )
)

Another solution is using FINDSTR with option /X to get a positive result only if searched string matches an entire line.

@echo off

if not exist FoldersCreated.txt cd . > FoldersCreated.txt

for /F "tokens=*" %%A in ('dir /A-D /B /ON *.mp4') do (
    %SystemRoot%\System32\findstr.exe /I /L /M /X /C:"%%~nA" FoldersCreated.txt >NUL
    if errorlevel 1 (
        md "%%~nA"
        copy "%%~fA" "%%~nA\prefix_%%~nxA"
        echo %%~nA>>FoldersCreated.txt
    )
)

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • copy /?
  • dir /?
  • echo /?
  • find /?
  • findstr /?
  • for /?
  • if /?
  • md /?

ATTENTION:

Care must be taken on second solution on line echo %%~nA>>FoldersCreated.txt regarding trailing spaces. There should be no trailing space as otherwise FINDSTR never exits with 0 for an entire line match.

The code posted by Aacini used as template for both solutions has 1 space at end of this line, i.e. there is foldersCreated.txtspace on this line.

This trailing space is interpreted by command processor as being part of the text to output by command echo and therefore executed was by command processor:

echo Test1  1>>FoldersCreated.txt
echo Test  1>>FoldersCreated.txt

So the space at end of code line is moved after file name and is therefore written also into the text file. As there is no trailing space in search string on calling FINDSTR, there is never an entire line match.

It is no solution to use double quotes around file name, i.e.

echo %%~nA>>"FoldersCreated.txt"

Also with double quotes a trailing space is moved by command processor to end of text to output by command echo.

It is also no solution using

>>FoldersCreated.txt echo %%~nA

as a space at end of this line must be nevertheless avoided because command processor executes this line also as:

echo %%~nA 1>>FoldersCreated.txt 

So any space after %%~nA would be nevertheless part of the text to output by echo.




回答2:


@echo off

if not exist foldersCreated.txt cd . > foldersCreated.txt

for /f "tokens=*" %%A in ('dir /b *.mp4') do (
   find "%%~nA" foldersCreated.txt > NUL
   if errorlevel 1 (
      md "%%~nA"
      copy "%%~fA" "%%~nA\prefix_%%~nxA"
      echo %%~nA>> foldersCreated.txt 
   )
)


来源:https://stackoverflow.com/questions/34296491/batch-file-that-remembers-what-was-copied

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!