Batch file 修剪字符串内容并重命名文件

Batch file 修剪字符串内容并重命名文件,batch-file,text-files,Batch File,Text Files,在一个文本文件中,我有1000行,每行有以下数据: ABCDqwqqwq321890821dsapodsaidadopd-9sa-9asd-9sa00sahjkhjsakdhdsddsad JhKyy120320171212 我需要删除每行中的字符(90个字符以后) 并将文件另存为Test\u DDMMYYYY.txt 下面是我的代码,我无法获得输出 有什么建议吗 @echo off &setlocal (for /f "delims

在一个文本文件中,我有1000行,每行有以下数据:

ABCDqwqqwq321890821dsapodsaidadopd-9sa-9asd-9sa00sahjkhjsakdhdsddsad                           JhKyy120320171212
我需要删除每行中的字符(90个字符以后) 并将文件另存为
Test\u DDMMYYYY.txt

下面是我的代码,我无法获得输出

有什么建议吗

@echo off &setlocal
(for /f "delims=" %%a in (*.*txt) do (
    set "line=%%a"
    setlocal enabledelayedexpansion
    set "line=!line:~,90!"
    echo(!line!
    endlocal
))>Test_DDMMYYYY.txt
还使用此代码重命名txt文件:

@echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime  ^| find "."') do set "dt=%%a"
set "YY=%dt:~2,2%"
set "YYYY=%dt:~0,4%"
set "MM=%dt:~4,2%"
set "DD=%dt:~6,2%"

set datestamp=%DD%%MM%%YYYY%
set fullstamp=%DD%%MM%%YYYY%

ren "C:\test\Test_.txt" "Test_%fullstamp%.txt"

例如,将不为空且不以分号开头的每一行复制到文件名中本地日期格式为
DDMMYYYY
且在前90个字符后截断每一行的批处理代码可以是:

@echo off
if not exist "Test.txt" goto :EOF

setlocal EnableExtensions EnableDelayedExpansion
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocalDate=%%I"
set "FileDate=%LocalDate:~6,2%%LocalDate:~4,2%%LocalDate:~0,4%

del "Test_%FileDate%.txt" 2>nul
for /F "usebackq delims=" %%I in ("Test.txt") do set "Line=%%I" & echo !Line:~0,90!>>"Test_%FileDate%.txt"
endlocal
命令

%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE
输出UTF-16小端编码,例如:

@echo off
if not exist "Test.txt" goto :EOF

setlocal EnableExtensions EnableDelayedExpansion
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocalDate=%%I"
set "FileDate=%LocalDate:~6,2%%LocalDate:~4,2%%LocalDate:~0,4%

del "Test_%FileDate%.txt" 2>nul
for /F "usebackq delims=" %%I in ("Test.txt") do set "Line=%%I" & echo !Line:~0,90!>>"Test_%FileDate%.txt"
endlocal

LocalDateTime=20170513195342.921000+120


因此,第一行是空行,第二行包含本地日期,格式为
YYYYMMDD
,位于为当前用户帐户定义的独立于区域和语言的等号设置之后。还有两行空行

FOR的命令在解析UTF-16 LE编码输出时存在一些问题,这导致将最后一个空行解释为仅包含回车符的行,而不是空行。有关此问题的详细信息,请参见上的答案

此处使用的命令FOR使用等号作为分隔符,将每一行拆分为两个子字符串(标记),因为
delims==
,并且只将第二个字符串分配给循环变量
I
,因为
tokens=2
。这意味着
20170513195342.921000+120
被分配给环境变量
LocalDate

最后一个空行被解释为带回车符的行的问题得到了解决,因为
tokens=2
,因为带回车符的行不能被分成两个标记,因此WMIC输出的错误解释的最后一个空行在这里也被for忽略

使用带有3个字符串替换的命令SET将本地日期/时间字符串重新格式化为仅
DDMMYYYY

提示:使用
yyyyymmdd
或可读性更好的
YYYY-MM-DD
的文件名在按文件名排序显示时会自动按日期排序。因此,
yyyyymmdd
YYYY-MM-DD
将优于
DDMMYYYY
作为文件名中的日期格式

然后,如果输出文件已经存在,则删除该输出文件,并将输出文件不存在上的错误消息重定向到设备
NUL
,以抑制该错误消息

第二个FOR解析文件
Test.txt
的行,即使由于选项
usebackq
而将文件名括在双引号中。空行也会被跳过,以分号开头的行也会被跳过。但是,由于选项
delims=
关闭了空格和水平制表符的默认拆分,并且只进一步处理第一个子字符串,因此处理所有其他行时不会拆分行。因此,在处理命令行之前,每个不以分号开头的非空行都被分配给循环变量
I

该行接下来分配给环境变量
line

注意1:由于启用了延迟扩展(根据需要)。下一步使用此解决方案,包含1个或多个感叹号的行将无法正确处理,因为将每个感叹号解释为对延迟扩展的环境变量的引用的开始或结束。因此,如果文件在每行的前90个字符中也包含感叹号,则需要使用不同的批处理代码

注2:输入文件中有问题的已发布行只有68个字符,并且没有将该行应写入的内容发布到输出文件中。我希望我对任务的理解是正确的

操作员
在一个命令行上指定两个命令,在命令
设置“行=%%I”后执行
再执行一个命令,仅输出输入文件中的前90个字符,并将此输出从句柄STDOUT重定向到文件名中带有本地日期的文件,并将此行附加到现有输出文件内容

FOR循环中的行截断为前90个字符需要延迟扩展或使用不同的代码,如使用子例程

一旦逐行处理完输入文件
Test.txt
,将恢复先前的命令处理环境并终止批处理文件的执行

以下是一种替代解决方案,可避免使用延迟扩展:

@echo off
if not exist "Test.txt" goto :EOF

setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocalDate=%%I"
set "FileDate=%LocalDate:~6,2%%LocalDate:~4,2%%LocalDate:~0,4%

del "Test_%FileDate%.txt" 2>nul
for /F "usebackq delims=" %%I in ("Test.txt") do set "Line=%%I" & call :OutputLine
endlocal
goto :EOF

:OutputLine
>>"Test_%FileDate%.txt" echo %Line:~0,90%
goto :EOF
这里使用一个子例程将每行的前90个字符输出到输出文件

重定向操作符
>
和输出文件名首先在命令行中指定,因为

echo %Line:~0,90%>>"Test_%FileDate%.txt"
可能导致立即展开环境变量,并在错误的文件输出中以空格和范围
1
9
的数字结尾的行

如果要输出的行包含对Windows命令解释器具有特殊意义的字符,例如
&
|
,,则此解决方案也不起作用。。。Windows命令解释器并不是真正为文本编辑而设计的。文本编辑器是为文本编辑而设计的

第一个解决方案重写为处理当前目录中的每个*.txt文件,但输出文件也写入当前目录

@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "LocalDate=%%I"
set "FileDate=%LocalDate:~6,2%%LocalDate:~4,2%%LocalDate:~0,4%

del "Test_%FileDate%.txt" 2>nul
for /F "delims=" %%T in ('dir *.txt /A-D /B 2^>nul') do for /F "usebackq delims=" %%I in ("%%T") do set "Line=%%I" & echo !Line:~0,90!>>"Test_%FileDate%.txt"
endlocal
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "delims=" %%T in ('dir *.txt /A-D /B 2^>nul') do (
    del "%%~nT.tmp" 2>nul
    for /F "usebackq delims=" %%I in ("%%T") do set "Line=%%I" & echo !Line:~0,90!>>"%%~nT.tmp"
    if exist "%%~nT.tmp" (
        %SystemRoot%\System32\fc.exe "%%~nT.tmp" "%%T" /A >nul
        if errorlevel 1 ( move /Y "%%~nT.tmp" "%%T" ) else ( del "%%~nT.tmp" )
    )
)
endlocal
文件内容处理FOR循环嵌套在另一个FOR循环中,该循环运行命令DIR,列出所有*.txt文件(而不是目录),因为
/A-D
为裸格式(仅文件名和文件扩展名没有路径),因为
/B

这是逗号的文件名列表