将.txt文件重命名为文件的第一行,并将“()”添加到重复项

时间:2019-10-20 21:36:04

标签: batch-file

我正在尝试使用目录的第一行重命名目录中的200多个.txt文件。这些文件包含IP地址,格式为12.345.678.90。我发现一个确实可以做到这一点,只是重复项根本没有被重命名。

我已经编辑了(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地址),然后将文件重命名为内容的第一行。

1 个答案:

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