这里是输入文件:
!~ItemID~RevID~DsetType~DsetName~DsetDesc~FileRef~File~RelationName
DR_QPC_M999~A~PDFA~DR_QPC_M999_A_001~~PDF~.\APR28_Batch1\DR_QPC_M999\A\DR_QPC_M999_A_001.pdf~IMAN_specification
DR_QPC_M999~A~PDFA~DR_QPC_M999_A_001~Imported QPC~PDF~.\APR28_Batch1\DR_QPC_M999\A\DR_QPC_M999_A_001.pdf~IMAN_specification
我在下面写了这个脚本来检查第三个值并根据该值更新第六个值。
所以,映射是这样工作的
如果第三个值是 PDFA --> 将第三个值 PDFA 更新为 R8PDFA
然后检查第 6 个值是否为 PDF 然后 --> 将第 6 个值更新为 R8PDFA.
我得到的输出:
!~ItemID~RevID~DsetType~DsetName~DsetDesc~FileRef~File~RelationName
DR_QPC_M999~A~R8PDFA~DR_QPC_M999_A_001~PDF~.\APR28_Batch1\DR_QPC_M999\A\DR_QPC_M999_A_001.pdf~IMAN_specification~
DR_QPC_M999~A~R8PDFA~DR_QPC_M999_A_001~Imported QPC~R8PDFA~.\APR28_Batch1\DR_QPC_M999\A\DR_QPC_M999_A_001.pdf~IMAN_specification
问题出在第二行: 如果输入值是这样的:
DR_QPC_M999~A~PDFA~DR_QPC_M999_A_001~~PDF~.\APR28_Batch1\DR_QPC_M999\A\DR_QPC_M999_A_001.pdf~IMAN_specification
也就是说,如果它有两个 Back to back
~~
这样它就不会把它当作两个单独的分隔符。但是如果我像~ ~
一样输入输入文件,脚本就可以工作了。
需要一个批处理脚本来解决这个问题。
@ECHO OFF
SETLOCAL
rem The following settings for the directories and filenames are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q76161584.txt"
SET "outfile=%destdir%\outfile.txt"
(
FOR /f "usebackqdelims=" %%e IN ("%filename1%") DO (
SET "line=%%e"
CALL :process
)
)>"%outfile%"
GOTO :EOF
:process
:: remove variables starting #
FOR /F "delims==" %%y In ('set # 2^>Nul') DO SET "%%y="
SET "#line=%line%"
SET /a #index=-1
:nextfield
SET /a #field+=1
SET /a #fieldlength=-1
:nextchar
SET /a #index+=1
SET /a #fieldlength+=1
SET "#char=%line:~0,1%"
SET "line=%line:~1%"
IF "%#char%" neq "~" GOTO nextchar
IF %#field%==3 (
SET /a #field3end=#index
SET /a #field3start=#index-#fieldlength
SET /a #field3length=#fieldlength
)
IF %#field%==6 (
SET /a #field6end=#index
SET /a #field6start=#index-#fieldlength
SET /a #field6length=#fieldlength
GOTO subs
)
GOTO nextfield
:subs
IF %#field3length% neq 4 GOTO nosubs
CALL SET "test=%%#line:~%#field3start%,4%%"
IF "%test%" neq "PDFA" GOTO nosubs
IF %#field6length% neq 3 GOTO sub3
CALL SET "test=%%#line:~%#field6start%,3%%"
IF "%test%" equ "PDF" CALL SET "#line=%%#line:~0,%#field6start%%%R8PDFA%%#line:~%#field6end%%%"
:sub3
CALL SET "#line=%%#line:~0,%#field3start%%%R8PDFA%%#line:~%#field3end%%%"
:nosubs
ECHO %#line%
GOTO :eof
OK - 回到基础。由于可用的测试数据有限,这个过程对我有用。
将每行数据依次赋值给
%%e
和line
通过逐个字符处理
line
来计算每个字段的开始和长度。
记录字段 3 和 6 的开始和长度。
在找到字段 6 时应用替换规则。
不清楚是否只有在字段3发生替换时才进行字段6的替换。我假设它是。
然后必须以相反的顺序执行替换,因为每个替换都会影响后面字段的起始位置。
您的问题中有很多未指定的细节。例如:
下面的代码假设前面所有问题的答案都是:否。
@echo off
setlocal DisableDelayedExpansion
set "header="
(for /F "delims=" %%a in (input.txt) do (
if not defined header (
set "header=1"
echo %%a
) else (
call :processLine "%%~a" < NUL
)
)) > output.txt
goto :EOF
:processLine
setlocal EnableDelayedExpansion
set "line=%~1"
set "i=0"
set "changed3="
:nextField
set /A i+=1
set "rest=%line:*~=%"
if "%rest%" equ "%line%" goto endFields
if "%rest:~0,1%" neq "~" (
set "field=!line:%rest%=!"
if %i% equ 3 if "!field!" equ "PDFA~" (
set "field=R8PDFA~"
set "changed3=1"
)
if %i% equ 6 if "!field!" equ "PDF~" if defined changed3 (
set "field=R8PDFA~
)
set /P "=!field!"
) else (
set "field=!line:%rest:~1%=!"
set /P "=!field!"
set /A i+=1
set "rest=%rest:~1%"
)
set "line=%rest%"
goto nextField
:endFields
echo %line%
exit /B
该方法包括从行的开头消除直到第一个
~
字符并获得余数。然后,从该行中删除此余数以获得第一个以 Tilda 分隔的字段。重复此过程,直到处理完所有字段。
如果上述问题之一的答案是肯定的,则应修改代码。其中一些要点可以通过非常简单的方式实现,有些则不能……