批处理文件以从具有第一个字段匹配的另一个文件中添加一个文件中的列
batch file to add a column in a file from another file with first field matching
我有两个文件:
HR.txt
12345,Fred,Jones,Sales
12346,Sam,Smith,Sales
12347,Jane,Doe,Purchasing
和
JCode.txt
12345,July
12346,May
12347,June
我正在尝试创建文件 Output.txt
12345,Fred,Jones,Sales,July
12346,Sam,Smith,Sales,May
12347,Jane,Doe,Purchasing,June
我尝试了几种不同的 findstr 组合,在批处理文件中调用批处理文件,但无法使输出文件工作。我的主批次调用次要批次,将 jcode.txt 文件作为参数 %1 %2 发送,但我似乎无法将它们添加到相应行的末尾。
这是我目前所拥有的,在我无法使用 findstr
使管道工作之后
@Echo off&Setlocal EnableExtensions EnableDelayedExpansion
SET _test=%1
set _test
( for /f "tokens=1-5 delims=," %%A in (hr.txt) do (
IF "%_test%"==%%A
echo %%A,%%B,%%C,%%D,%_test%
) Else
echo %%A,%%B,%%C,%%D
)
)
) >newfile3.csv
我意识到用另一种语言会更容易,但我仅限于通过批处理文件进行数据操作。
提前致谢...
根据您的两个输入文件和您想要的输出文件,根本不需要参数 %1
或 if
。相反,您需要从第二个文件的正确行中获取第二个标记,其中包含 for /f
和正确行的过滤器 (find "%%A"
)
@Echo off&Setlocal EnableExtensions EnableDelayedExpansion
(for /f "tokens=1-5 delims=," %%A in (hr.txt) do (
for /f "tokens=2 delims=," %%Z in ('find "%%A" jcode.txt') do (
echo %%A,%%B,%%C,%%D,%%Z
)
))>newfile3.csv
不需要延迟扩展(当你的脚本的其他部分不需要它时)
对于手头的任务,我看到以下选项:
输入文件 HR.txt
和 JCode.txt
的示例数据显示第一列的值完全相同,顺序相同,因此可以同时读取它们这些线可以按它们的位置合并,像这样:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_IN1FILE=HR.txt" & rem // (1st input file)
set "_IN2FILE=JCode.txt" & rem // (2nd input file)
rem // Determine least number of available lines:
for /F %%C in ('^< "%_IN1FILE%" find /C /V ""') do set "CNT=%%C"
for /F %%C in ('^< "%_IN2FILE%" find /C /V ""') do (
if %%C lss %CNT% set "CNT=%%C"
)
rem // Read both input files simultaneously:
9< "%_IN1FILE%" 8< "%_IN2FILE%" (
setlocal EnableDelayedExpansion
rem // Loop through the least number of available lines:
for /L %%I in (1,1,%CNT%) do (
rem // Read a line from the 1st input file:
<&9 (set "LINE1=" & set /P LINE1="")
rem // Read a line from the 2nd input file:
<&8 (set "LINE2=" & set /P LINE2="")
rem /* Build and return an output line consisting of a line of the 1st input file
rem and a line of the 2nd input file with the first field value removed: */
if defined LINE1 if defined LINE2 echo(!LINE1!!LINE2:*,=,!
)
endlocal
)
endlocal
exit /B
注意事项:
- 输入文件的第一列必须以相同的顺序完全包含相同的数据;
- 行必须短于大约 1K bytes/characters;
- 两个文件的行数必须相等;
如果输入文件第一列中的数据可能顺序不同或项目数量不同,则可以使用两个嵌套循环,如下所示:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_IN1FILE=HR.txt" & rem // (1st input file)
set "_IN2FILE=JCode.txt" & rem // (2nd input file)
rem // Loop through lines of 1st input file and split at first `,`:
for /F "usebackq tokens=1* delims=, eol=," %%I in ("%_IN1FILE%") do (
rem // Loop through lines of 2nd input file and split at first `,`:
for /F "usebackq tokens=1* delims=, eol=," %%K in ("%_IN2FILE%") do (
rem /* Check first field values of the currently iterated lines of both input
rem files against equality and in case build and return an output line: */
if "%%I"=="%%K" echo(%%I,%%J,%%L
)
)
endlocal
exit /B
注意事项:
- 行必须短于大约 8K bytes/characters;
- 两个输入文件的第一列和第二列值不能为空;
作为第一列中数据不同的情况的替代方案,findstr
command 可用于从其他文件中获取每行的匹配行,如下所示:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_IN1FILE=HR.txt" & rem // (1st input file)
set "_IN2FILE=JCode.txt" & rem // (2nd input file)
rem // Loop through lines of 1st input file and split at first `,`:
for /F "usebackq tokens=1* delims=, eol=," %%I in ("%_IN1FILE%") do (
rem /* Search the line in the 2nd input file that begins with the first field
rem value of the 1st input file and capture it: */
for /F "tokens=1* delims=, eol=," %%K in ('
findstr /B /C:"%%I," "%_IN2FILE%"
') do (
rem // Build and return an output line:
echo(%%I,%%J,%%L
)
)
endlocal
exit /B
注意事项:
- 行必须短于大约 8K bytes/characters;
- 两个输入文件的第一列和第二列值不能为空;
\
第一列值 JCodes.txt
可能会导致意外输出,因为 findstr
使用该字符转义某些元字符(即使在文字搜索模式下!);
要将输出数据写入文件,请使用输出 redirection >
(对于上述所有脚本):
consolidate.bat > "consolidated.txt"
我有两个文件:
HR.txt
12345,Fred,Jones,Sales
12346,Sam,Smith,Sales
12347,Jane,Doe,Purchasing
和
JCode.txt
12345,July
12346,May
12347,June
我正在尝试创建文件 Output.txt
12345,Fred,Jones,Sales,July
12346,Sam,Smith,Sales,May
12347,Jane,Doe,Purchasing,June
我尝试了几种不同的 findstr 组合,在批处理文件中调用批处理文件,但无法使输出文件工作。我的主批次调用次要批次,将 jcode.txt 文件作为参数 %1 %2 发送,但我似乎无法将它们添加到相应行的末尾。
这是我目前所拥有的,在我无法使用 findstr
使管道工作之后@Echo off&Setlocal EnableExtensions EnableDelayedExpansion
SET _test=%1
set _test
( for /f "tokens=1-5 delims=," %%A in (hr.txt) do (
IF "%_test%"==%%A
echo %%A,%%B,%%C,%%D,%_test%
) Else
echo %%A,%%B,%%C,%%D
)
)
) >newfile3.csv
我意识到用另一种语言会更容易,但我仅限于通过批处理文件进行数据操作。
提前致谢...
根据您的两个输入文件和您想要的输出文件,根本不需要参数 %1
或 if
。相反,您需要从第二个文件的正确行中获取第二个标记,其中包含 for /f
和正确行的过滤器 (find "%%A"
)
@Echo off&Setlocal EnableExtensions EnableDelayedExpansion
(for /f "tokens=1-5 delims=," %%A in (hr.txt) do (
for /f "tokens=2 delims=," %%Z in ('find "%%A" jcode.txt') do (
echo %%A,%%B,%%C,%%D,%%Z
)
))>newfile3.csv
不需要延迟扩展(当你的脚本的其他部分不需要它时)
对于手头的任务,我看到以下选项:
输入文件
HR.txt
和JCode.txt
的示例数据显示第一列的值完全相同,顺序相同,因此可以同时读取它们这些线可以按它们的位置合并,像这样:@echo off setlocal EnableExtensions DisableDelayedExpansion rem // Define constants here: set "_IN1FILE=HR.txt" & rem // (1st input file) set "_IN2FILE=JCode.txt" & rem // (2nd input file) rem // Determine least number of available lines: for /F %%C in ('^< "%_IN1FILE%" find /C /V ""') do set "CNT=%%C" for /F %%C in ('^< "%_IN2FILE%" find /C /V ""') do ( if %%C lss %CNT% set "CNT=%%C" ) rem // Read both input files simultaneously: 9< "%_IN1FILE%" 8< "%_IN2FILE%" ( setlocal EnableDelayedExpansion rem // Loop through the least number of available lines: for /L %%I in (1,1,%CNT%) do ( rem // Read a line from the 1st input file: <&9 (set "LINE1=" & set /P LINE1="") rem // Read a line from the 2nd input file: <&8 (set "LINE2=" & set /P LINE2="") rem /* Build and return an output line consisting of a line of the 1st input file rem and a line of the 2nd input file with the first field value removed: */ if defined LINE1 if defined LINE2 echo(!LINE1!!LINE2:*,=,! ) endlocal ) endlocal exit /B
注意事项:
- 输入文件的第一列必须以相同的顺序完全包含相同的数据;
- 行必须短于大约 1K bytes/characters;
- 两个文件的行数必须相等;
如果输入文件第一列中的数据可能顺序不同或项目数量不同,则可以使用两个嵌套循环,如下所示:
@echo off setlocal EnableExtensions DisableDelayedExpansion rem // Define constants here: set "_IN1FILE=HR.txt" & rem // (1st input file) set "_IN2FILE=JCode.txt" & rem // (2nd input file) rem // Loop through lines of 1st input file and split at first `,`: for /F "usebackq tokens=1* delims=, eol=," %%I in ("%_IN1FILE%") do ( rem // Loop through lines of 2nd input file and split at first `,`: for /F "usebackq tokens=1* delims=, eol=," %%K in ("%_IN2FILE%") do ( rem /* Check first field values of the currently iterated lines of both input rem files against equality and in case build and return an output line: */ if "%%I"=="%%K" echo(%%I,%%J,%%L ) ) endlocal exit /B
注意事项:
- 行必须短于大约 8K bytes/characters;
- 两个输入文件的第一列和第二列值不能为空;
作为第一列中数据不同的情况的替代方案,
findstr
command 可用于从其他文件中获取每行的匹配行,如下所示:@echo off setlocal EnableExtensions DisableDelayedExpansion rem // Define constants here: set "_IN1FILE=HR.txt" & rem // (1st input file) set "_IN2FILE=JCode.txt" & rem // (2nd input file) rem // Loop through lines of 1st input file and split at first `,`: for /F "usebackq tokens=1* delims=, eol=," %%I in ("%_IN1FILE%") do ( rem /* Search the line in the 2nd input file that begins with the first field rem value of the 1st input file and capture it: */ for /F "tokens=1* delims=, eol=," %%K in (' findstr /B /C:"%%I," "%_IN2FILE%" ') do ( rem // Build and return an output line: echo(%%I,%%J,%%L ) ) endlocal exit /B
注意事项:
- 行必须短于大约 8K bytes/characters;
- 两个输入文件的第一列和第二列值不能为空;
\
第一列值JCodes.txt
可能会导致意外输出,因为findstr
使用该字符转义某些元字符(即使在文字搜索模式下!);
要将输出数据写入文件,请使用输出 redirection >
(对于上述所有脚本):
consolidate.bat > "consolidated.txt"