batch-file - 将 .txt 文件重命名为文件中的第一行并将“()”添加到重复项
问题描述
我正在尝试.txt
使用其内容的第一行重命名目录中的 200 多个文件。这些文件包含格式的 IP 地址,例如12.345.678.90
. 我找到了一个批处理文件,它完全可以做到这一点,只是重复项根本没有被重命名。
我已经编辑(根据我的需要),并在 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
文件并添加()
一些重复项,以便仍然可以使用相同的批处理文件重命名重复项(当然是通过编辑),还是需要新的批处理?有什么建议吗?或欢迎新代码。
最终,重复的文件可以合并为一个(因为它们无论如何都会包含相同的 IP 地址),然后将文件重命名为它们的第一行内容。
解决方案
对于多个线程,您可能会遇到导致冲突的竞争条件。我开始的方式是使用线程号来避免冲突。我正在展示未经测试的示例代码。由于 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
推荐阅读
- sabre - 测试 API 工作流 -session createRQ-FAILED
- r - 无法在 RStudio 中加载插入符号库
- javascript - Chrome 扩展:如何在其中运行的内容脚本中获取 tabId
- matlab - 替换每个包含 '#' 的字符串
- wordpress - WP - 子主题获取主题目录
- swift - 我的自定义 SKNode 没有调用 onTouchesBegan()
- python - 使用 Python 中的 Watson Assistant / Watson 对话
- javascript - 不再引用对象时的clearInterval?
- angular - 我可以在我的服务中使用小吃店吗?
- html - 获取背景图像以在两个背景图像之间重叠另一个背景图像元素