使用文件中第一行的部分文本重命名txt文件

3
我需要一个批处理文件中的代码,用于重命名从SAP创建的银行文件(我是SAP专业人员),这些文件存储在服务器上的某个位置。
问题:所有银行文件都从SAP中的序列表中获得名称(日期+编号)。在将它们发送到银行之前,它们必须具有特定的名称结构。
我有一个代码,到目前为止一直很好用。现在的问题是,我从SAP发送了一批(多个)文件,它们的名称是随机的。 在每个文件的第一行中,有一个唯一的批次ID,即银行序列号,文件必须按此顺序命名。 我已经做了很多VBA编程,但我在这个主题上不太强。
所需解决方案:我需要的是对于每个文件,它应该读取文件的第一行并获取位置71和4个位置向前,将其保存在一个变量中,并将其添加到文件名的末尾。
示例:如果来自SAP的原始文件名为20160301-001.txt,则我想将其重命名为“P.00934681758.005.TBII.00000xxxx.txt”(其中“xxxx”是文件第一行中的位置71到74)。
今天它浏览了很多银行目录,但是下面您可以找到今天的代码(除了在此代码中重新编号“a”,从而不超过9个文件之外,它可以工作),我想用文件的这4位数字替换它:
今天的名称:P.00934681758.005.TBII.00000!a!.dat(“a”是一个变量)
新名称:P.00934681758.005.TBII.00xxxx.dat(“xxxx”是来自文件的数字)
今天的代码(其中一部分-显示2个“扫描”目录):
    @echo off & setlocal EnableDelayedExpansion 

REM Start by renaming all files in each folder to the namerule of the bank

cd PL270\UT01

set a=1

for /f "delims=" %%i in ('dir /b *') do (
    if not "%%~nxi"=="%~nx0" (
        ren "%%i" "P.00934681758.002.TBII.00000!a!".dat 
        set /a a+=1
 )
) 

cd..
cd..\PL570\UT01

set a=1

for /f "delims=" %%i in ('dir /b *') do (
    if not "%%~nxi"=="%~nx0" (
        ren "%%i" "P.00934681758.005.TBII.00000!a!".dat 
        set /a a+=1
 )
) 

今天的代码是在一个 *.bat 文件中运行的,安排在服务器上每5分钟运行一次。
非常感谢所有的帮助:-)
此致 敬礼 Solve

所以你的 a 应该是每个文件第一行的ID吗? - npocmaka
2个回答

0
根据我的理解,您需要将硬编码的a替换为从您正在重命名的文件中读取的代码。
for /f "delims=" %%i in ('dir /b *') do (
    set /p fline=<"%%i"
    set code=!fline:~70,4!
    echo !code!
    if not "%%~nxi"=="%~nx0" (
        ren "%%i" "P.00934681758.002.TBII.00000!code!".dat 
        set /a a+=1
 )
)

(曾经我为SAP工作过-那是我做过的最无聊的工作...)


非常感谢npocmaka:-) 这个工作得很好。简单而实用。 - Solve
顺便说一下,我也是一个金融家 - 这可能解释了为什么我喜欢使用SAP(我知道有些人认为它很无聊 :) 。我和女儿一起拥有自己的公司,我们已经被预订超过10年 - 没有多少人可以这样说:-) - Solve

0
以下脚本遍历给定的目录树并搜索匹配的文件。如果文件名以格式YYYYMMDD开头,后跟一个-,后跟一个数字,后跟扩展名.txt,则认为该文件与所需文件匹配。对于每个找到的文件,从第一行中提取要求的字符,然后将它们附加到前缀P.00934681758.005.TBII.00上,并附加扩展名.dat
批处理文件的行为可以通过在开头定义的常量来控制。要了解它的工作原理和发生的情况,请查看整个文件中的rem注释。
以下是代码:
@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem Definition of constants:
set "LOCATION=%~dp0" & rem Working directory; `%~dp0` is container, `.` is current;
set "RECURSIVE=#" & rem Flag to walk through working directory recursively, if defined;
set "SEPARATOR=-" & rem Separator character of original file name (one character!);
set "PATTERN=????????%SEPARATOR%*.txt" & rem Search pattern for `dir`;
rem Filter for `findstr /R` to match only correct file names (`.*` deactivates it):
set "REGEX=[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%SEPARATOR%[0-9][0-9]*\.txt";
rem Filter for date prefix in file names (fixed date like `YYYYMMDD`, all files if empty):
set "TODAY=%DATE:~,4%%DATE:~5,2%%DATE:~8,2%" & rem Expected `%DATE%` format: `YYYY/MM/DD`;
set "NEWNAME=P.00934681758.005.TBII.00" & rem Beginning of new file name;
set "NEWEXT=.dat" & rem New file extension;
set "NUMLINE=0" & rem Zero-based line number where to extract characters from;
set "POSITION=70,4" & rem Zero-based start position, number of characters (length);
set "FORCE=#" & rem Flag to force extracted characters not to be empty, if defined;

rem Change to working directory:
pushd "%LOCATION%" || (
    >&2 echo Cannot find "%LOCATION%". & exit /B 1
)
rem Initialise some variables:
set /A NUMLINE+=0
if %NUMLINE% LEQ 0 (set "NUMSKIP=") else (set "NUMSKIP=skip^=%NUMLINE%^ ")
if defined RECURSIVE (set "RECURSIVE=/S ")
rem Walk through directory (tree) and search for matching file names (sorted by name):
for /F "eol=| delims=" %%F in ('
    dir /B %RECURSIVE%/A:-D /O:-N-D "%PATTERN%" ^| ^
        findstr /R /C:"^%REGEX%$" /C:"\\%REGEX%$"
') do (
    rem Split file name by given separator:
    for /F "eol=| tokens=1,* delims=%SEPARATOR%" %%I in ("%%~nxF") do (
        set "PREFIX=%%I"
        set "SUFFIX=%%J"
        setlocal EnableDelayedExpansion
        rem Check whether first part of file name matches today's date:
        if "%TODAY%"=="" (set "TODAY=!PREFIX!")
        if "!PREFIX!"=="!TODAY!" (
            set "OLDNAME=!PREFIX!%SEPARATOR%!SUFFIX!"
            rem Extract characters from predefined position from file (sub-routine):
            call :EXTRACT PORTION "!OLDNAME!"
            if defined FORCE (
                rem Check extracted character string if empty optionally:
                if not defined PORTION (
                    >&2 echo Nothing at position ^(%POSITION%^). & popd & exit /B 1
                )
            )
            rem Build new file name using extracted character string:
            set "BUILTNAME=%NEWNAME%!PORTION!%NEWEXT%"
            rem Check whether a file with the new name already exists:
            if not exist "!BUILTNAME!" (
                rem Actually rename file here (as soon as `ECHO` is removed!):
                ECHO ren "!OLDNAME!" "!BUILTNAME!"
            ) else (
                >&2 echo "!BUILTNAME!" already exists. & popd & exit /B 1
            )
        ) else (
            endlocal
            rem First part of file name does not match today's date, so leave loop:
            goto :CONTINUE
        )
        endlocal
    )
)
:CONTINUE
popd

endlocal
exit /B

:EXTRACT PORTION "FileSpec"
rem Sub-routine to extract characters from a file at a given position;
set "PART="
setlocal DisableDelayedExpansion
rem Read specified line from given file:
for /F usebackq^ %NUMSKIP%delims^=^ eol^= %%L in ("%~2") do (
    set "LINE=%%L"
    if defined LINE (
        setlocal EnableDelayedExpansion
        rem Extract specified sub-string of read line by position and length:
        set "PART=!LINE:~%POSITION%!"
        if  defined PART (
            for /F delims^=^ eol^= %%S in ("!PART!") do (
                endlocal
                set "PART=%%S"
            )
        ) else (
            endlocal
        )
    )
    rem Do not read any more lines from the file, leave loop:
    goto :QUIT
)
:QUIT
rem Return extracted character string:
endlocal & set "%~1=%PART%"
exit /B

脚本只有在您不在ren命令前面删除大写的ECHO时才不会重命名。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接