这是我想要实现的目标: 我在一个文件夹中有多个文本文件,具有任意名称。我想阅读文本文件,并从第二行内容中提取两个短语,然后用于重命名文件。 以下是相关文件的典型结构(前3行):
--------------------------------------------------------------------------------
Company Pty Ltd EXAMPLE SUMMARY LIST Model : MODEL_1
--------------------------------------------------------------------------------
我想获取模型名称和列表标题以创建(对于此示例)文件“MODEL_1 EXAMPLE SUMMARY LIST.txt” 我的问题是“标题”在行上的长度和位置不同(但总是在第18和第41个字符之间)。 我使用一些代码,我发现在标题结合代码之前和之后解析空间重命名文件,但我不知道如何添加“模型”部分或如何使其递归(因为它只处理一个每次运行批处理文件时都有文件。)
这是我到目前为止的代码:
@echo off&setlocal
for /f "delims=" %%i in ('dir /a-d/b *.txt') do (
set "nname="
set "fname=%%~i"
for /f "usebackqskip=1delims=" %%f in ("%%~i") do if not defined nname set "nname=%%f"
setlocal enabledelayedexpansion
set "nname=!nname:~18,41!"
set "nname=!nname!"
:: **** Begin space compression code ****
:loop
if defined nname (
set "new=!nname: = !"
if "!new!" neq "!nname!" (
set "nname=!new!"
goto :loop
)
)
if defined nname if "!nname:~0,1!" equ " " set "nname=!nname:~1!"
if defined nname if "!nname:~-1!" equ " " set "nname=!nname:~0,-1!"
:: **** End space compression code ****
rename "!fname!" "!nname!.txt"
endlocal
)
任何有关如何获得我所需要的结果的建议都将不胜感激。
答案 0 :(得分:1)
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
PUSHD "%sourcedir%"
FOR /f "delims=" %%a IN ('dir /b /a-d q*.txt') DO (
SET "line="
FOR /f "usebackq skip=1 tokens=1* delims=:" %%b IN ("%%a") DO IF NOT DEFINED line (
SET "line=%%b"&SET "model=%%c"
CALL :process
ECHO(REN "%%a" "!model:~1! !line!.txt"
ECHO(used "%%b"
)
)
popd
GOTO :EOF
:process
SET "line=%line:~17,-6%"
:stripL
IF "%line:~0,1%"==" " SET "line=%line:~1%"&GOTO stripL
:stripR
IF "%line:~-1%"==" " SET "line=%line:~0,-1%"&GOTO stripR
GOTO :eof
您需要更改sourcedir
的设置以适合您的具体情况。
我使用了一个名为q28192545.txt
的文件,其中包含我的测试数据,并设置了q*.txt
的文件掩码,以确保只有q*.txt
个文件用于测试。
首先,暂时切换到相关目录。
然后获取仅文件名的目录,并依次将每个目录分配给%%a
使用变量line
作为标志并包含已处理的名称。首先清除line
以使其未定义,然后读取文件%%a
,跳过第一行并使用:
作为分隔符,将第二行指定为%%b
中的冒号和结肠的部分进入%%c
;将这些变量分配给正常的环境变量line
和model
。
由于现在定义了line
,因此不会对%%a
中的其余行进行处理。
处理line
- 首先删除前17个字符和后6个字符(不确定公司名称是否会占用超过17个字符 - 未指定)。最后6个字符是model
(冒号前)
现在删除左边的空格,然后向右移动一步,标题应该整齐地修剪。
从流程返回,重命名可以发生在model
中的字符串中(除了第一个字符,它将是一个空格)+一个空格_剩余的line
+ {{1 }}
最后,仅针对文档,显示引起重命名的行。
为了测试目的,所需的REN命令仅为.txt
。 在您确认命令正确后,将ECHO
更改为ECHO(REN
以实际重命名文件。
答案 1 :(得分:1)
编辑:修复了小错误
@echo off
setlocal EnableDelayedExpansion
rem For all text files in folder
for /F "delims=" %%a in ('dir /A-D /B *.txt') do (
rem Get the 2nd line and divide it at the colon
set "line="
for /F "usebackq skip=1 tokens=1,2 delims=:" %%b in ("%%a") do (
if not defined line (
set "line=%%b"
set "model=%%c"
)
)
rem Join the model plus all the words in line from char 18 take 41
set "nname="
for %%b in (!model! !line:~18^,41!) do set "nname=!nname! %%b"
rem Rename the file (remove additional space at beginning of nname)
ren "%%a" "!nname:~1!.txt"
)
此方法将放置在FOR命令中的单词与它们之间的空格连接起来。在您的示例中,FOR将是这样的:
for %%b in ( MODEL_1 EXAMPLE SUMMARY LIST ) do set "nname=!nname! %%b"
......这会产生这个:
set "nname= MODEL_1 EXAMPLE SUMMARY LIST"
......开头有一个额外的空间。当然,如果单词可能包含任何外卡或特殊字符,则此方法将无效...
答案 2 :(得分:0)
我看到的最大问题是您的外部:loop
循环中有一个标签(goto
)和for /f
。不要那样做。一旦到达goto
,外部循环就会中断。如果您需要在不中断循环的情况下使用goto
,请将相关代码块移到循环外部并使用call
。有关实现此目的的有用方法,请参阅this batch function tutorial。
使用正则表达式拆分可以更轻松地刮取模型和摘要。实际上并没有真正的批处理方式(除非你的路径中有sed
或grep
或类似的东西),但你可以很容易地调用JScript或VB Script或PowerShell。我个人更喜欢JScript,因为它很容易调用as a hybrid script,因为它具有已经熟悉的IE7 JavaScript语法(只需将“窗口”和“文档”对象替换为特定于Windows的方法和对象)。
所以无论如何,如果你上面的例子代表了你想要抓取的所有文件,那么可以通过拆分2个或更多的空格字符来处理模型部分的抓取。 JScript使这很容易。只需分开/\s\s+/
。
在外部:loop
循环中删除goto
和for
之后,您可以使用{{1}以递归方式搜索*.txt
脚本}循环。
for /r