基于变量(多个)内容重命名txt文件

时间:2015-01-28 12:41:59

标签: batch-file

这是我想要实现的目标: 我在一个文件夹中有多个文本文件,具有任意名称。我想阅读文本文件,并从第二行内容中提取两个短语,然后用于重命名文件。 以下是相关文件的典型结构(前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
)

任何有关如何获得我所需要的结果的建议都将不胜感激。

3 个答案:

答案 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;将这些变量分配给正常的环境变量linemodel

由于现在定义了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

使用正则表达式拆分可以更轻松地刮取模型和摘要。实际上并没有真正的批处理方式(除非你的路径中有sedgrep或类似的东西),但你可以很容易地调用JScript或VB Script或PowerShell。我个人更喜欢JScript,因为它很容易调用as a hybrid script,因为它具有已经熟悉的IE7 JavaScript语法(只需将“窗口”和“文档”对象替换为特定于Windows的方法和对象)。

所以无论如何,如果你上面的例子代表了你想要抓取的所有文件,那么可以通过拆分2个或更多的空格字符来处理模型部分的抓取。 JScript使这很容易。只需分开/\s\s+/

在外部:loop循环中删除gotofor之后,您可以使用{{1}以递归方式搜索*.txt脚本}循环。

for /r