我正在尝试使用目录的第一行重命名目录中的200多个.txt
文件。这些文件包含IP地址,格式为12.345.678.90
。我发现一个batch-file确实可以做到这一点,只是重复项根本没有被重命名。
我已经编辑了(em)(满足我的需要),并在Server2016和Windows10上测试了以下脚本,该脚本重命名了文件,但对重复文件不做任何操作。
@echo off
setlocal EnableDelayedExpansion
rem Multi-thread file rename program
if "%1" equ "Thread" goto ProcessBlock
rem Create the list of file names and count they
cd C:\Renamed_Files
set numFiles=0
(for %%f in (*.txt) do (
echo %%f
set /A numFiles+=1
)) > fileNames.tmp
rem Get number of threads and size of each block
set numThreads=%1
if not defined numThreads (
set /A numThreads=1, blockSize=numFiles
) else (
set /A blockSize=numFiles/numThreads
)
rem Create asynchronous threads to process block number 2 up to numThreads
if exist thread.* del thread.*
for /L %%t in (2,1,%numThreads%) do (
echo %time% > thread.%%t
start "" /B "%~F0" Thread %%t
)
rem Process block number 1
set count=0
for /F "delims=" %%f in (fileNames.tmp) do (
set /p line1=<%%f
ren "%%f" "!line1:~0,40!.txt"
set /A count+=1
if !count! equ %blockSize% goto endFirstBlock
)
:endFirstBlock
rem Wait for all asynchronous threads to end
if exist thread.* goto endFirstBlock
rem Delete the auxiliary file and end
del fileNames.tmp
goto :EOF
rem Process blocks 2 and up (asynchronous thread)
:ProcessBlock
set /A skip=(%2-1)*blockSize, count=0
for /F "skip=%skip% delims=" %%f in (fileNames.tmp) do (
set /p line1=<%%f
ren "%%f" "!line1:~0,40!.txt"
set /A count+=1
if !count! equ %blockSize% goto endBlock
)
:endBlock
del thread.%2
exit
我希望重命名.txt
文件并添加带有重复项的()
,以便仍然可以使用相同的批处理文件重命名这些重复项,(当然可以通过编辑)< / em>,还是需要新一批?有什么建议吗?或欢迎使用新代码。
最终,可以将重复的文件合并到一个文件中(因为它们始终将包含相同的ip地址),然后将文件重命名为内容的第一行。
答案 0 :(得分:0)
在使用多线程的情况下,您可能具有导致冲突的竞争条件。我 start 的方法是使用线程号来避免冲突。我正在显示未经测试的示例代码。由于DOS中括号的问题,我改为使用句点并向您推荐:
...
:ProcessBlock
set /A skip=(%2-1)*blockSize, count=0
for /F "skip=%skip% delims=" %%f in (fileNames.tmp) do call :ProcessBlockLoop "%%~f" %2
goto :eof
:ProcessBlockLoop
set /p line1=<"%~1"
set "filename=!line1:~0,40!"
:: Check for an existing file.
if not exist "%filename%.txt" goto :ProcessBlockLoopContinue
:: if we get here then there is an existing file.
set DupCnt=1
:ProcessBlockFilenameLoop
if not exist "%filename%.%2.%DupCnt%.txt" (
set filename=%filename%.%2.%DupCnt%
goto :ProcessBlockLoopContinue
)
:: increment our duplicate counter and try again
set /a DupCnt += 1
goto :ProcessBlockFilenameLoop
:ProcessBlockLoopContinue
:: Try the rename. If the rename fails, then reset the variables and loop again.
:: A retry counter should be added to avoid an infinite loop.
ren "%%f" "%filename%.txt" || set DupCnt=1&&set "filename=!line1:~0,40!"&&goto :ProcessBlockFilenameLoop
:: If we're here, the rename should have worked. You could double check again if desired.
set /A count+=1
if %count% equ %blockSize% (
del thread.%2
exit
)
goto :eof