使用批处理文件并排合并多个 csv 文件
Merge several csv file side by side using batch file
我正在寻找两个将几个 csv 文件合并为一个文件。但是我需要它们合并,以便列并排而不继续。
我的文件每次都有两列,我会通过提取每个文件的第二列并复制到另一个文件中来获得一个 csv 文件,这样我就会有一个包含 x 列的文件(第二个)。
例如
文件 1
A B
1 2
1 2
1 2
文件 2
A C
1 3
1 3
1 3
Filex
A X
1 x
1 x
1 x
结果
B C X
2 3 x
2 3 x
2 3 x
我发现了这个:Merge csv file side by side using batch file
但它只适用于两个文件,不会提取任何内容。
谢谢。
@ECHO OFF
SETLOCAL enabledelayedexpansion
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
SET /a $count=0
FOR %%a IN (q28850167*.txt) DO (
FOR /f "tokens=1,2*delims=: " %%b IN ('findstr /n /r "^" "%%a"') DO (
SET $%%b=!$%%b! %%d
IF !$count! LSS %%b SET /a $count=%%b
)
)
(
FOR /L %%a IN (1,1,%$count%) DO ECHO(!$%%a:~1!
)>newfile.txt
GOTO :EOF
我使用了包含您的数据的名为 q28850167*.txt
的文件进行测试。
产生 newfile.txt
清除所有从 $
开始的变量
对于匹配掩码的每个文件,通过 findstr/n
处理每一行以将 number :
应用到每一行的开头。 Select 第一列和第三列以上使用 :
和 Space 作为分隔符并附加到变量 $linenumber
跟踪最高行号在 $count
.
然后简单地从存储的数据中重现每一行。
以下所有解决方案都假设所有输入文件的格式一致且行数相同。
可以修改 Merge csv file side by side using batch file 中使用的技术来解析和支持 2 个以上的文件。我还在循环中打开和关闭延迟扩展,以保护可能出现在数据中的任何 !
。包含 !
的 FOR 变量如果在启用延迟扩展的情况下扩展,则会损坏:
@echo off
setlocal disableDelayedExpansion
3<"test2.txt" 4<"test3.txt" (
for /f "usebackq tokens=2 delims= " %%A in ("test1.txt") do (
set "A=%%A"
set /p "B=" <&3
set /p "C=" <&4
setlocal enableDelayedExpansion
echo !A! !B:* =! !C:* =!
endlocal
)
) >"result.txt"
使用 FOR 循环加上句柄 0 和 3-9,以上内容可以扩展为最多支持 9 个输入文件。如果输入超过 8 个,则需要多个循环。第一个循环可以处理前 9 个文件并将部分结果写入临时文件。连续循环可以从临时文件中读取并合并最多 8 个附加文件。
如果你的解析规则变得更复杂,上面的内容可能会变得很麻烦。
My JREPL.BAT hybrid JScript/batch utility 可用于高效解析和合并任意数量的文件,您可以根据需要修改正则表达式以解析几乎任何 csv 文件格式。
@echo off
setlocal
set "merge=jrepl ".*( .*)" "stdin.ReadLine()+" /j /f"
jrepl ".* (.*)" "" /f test1.txt | %merge% test2.txt | %merge% test3.txt >result.txt
理论上你可以使用任意数量的管道来支持你所有的输入文件,但如果你得到太多,它可能会变得低效。您可以使用临时文件暂存合并以保持效率。
最初在 this post 中描述的方法可以修改以处理可变数量的文件(最多 8 个),因此您只需将所需的文件放在参数中:
@echo off
setlocal DisableDelayedExpansion
rem MergeFiles.bat: Merge several files horizontally
rem Antonio Perez Ayala
rem Process files in the arguments and
rem assemble the lists of redirections and SET /P commands
set file1=%1
set "redirs="
set "commands="
set n=2
:nextFile
shift
if "%~1" equ "" goto endFiles
set /A n+=1
set "redirs=%redirs% %n%<%1"
set "commands=%commands% & set /P "part=!part:* =! " <&%n%"
goto nextFile
:endFiles
rem First file is read with FOR /F command
rem The rest of files are read via standard handles, starting at # 3
%redirs% (
for /F "usebackq delims=" %%a in (%file1%) do (
rem Get first part from first file
set "part=%%a"
rem Output parts from all files, excepting the last one
setlocal EnableDelayedExpansion
%commands:~3%
rem Output part from last file
echo !part:* =!
endlocal
)
) > result.txt
例如:
C:\> type file?.txt
file1.txt
A B
1 2
1 2
1 2
file2.txt
A C
1 3
1 3
1 3
fileX.txt
A X
1 x
1 x
1 x
fileY.txt
A Y
1 y
1 y
1 y
C:\> MergeFiles.bat file1.txt file2.txt fileX.txt fileY.txt
C:\> type result.txt
B C X Y
2 3 x y
2 3 x y
2 3 x y
我正在寻找两个将几个 csv 文件合并为一个文件。但是我需要它们合并,以便列并排而不继续。 我的文件每次都有两列,我会通过提取每个文件的第二列并复制到另一个文件中来获得一个 csv 文件,这样我就会有一个包含 x 列的文件(第二个)。
例如
文件 1
A B
1 2
1 2
1 2
文件 2
A C
1 3
1 3
1 3
Filex
A X
1 x
1 x
1 x
结果
B C X
2 3 x
2 3 x
2 3 x
我发现了这个:Merge csv file side by side using batch file
但它只适用于两个文件,不会提取任何内容。
谢谢。
@ECHO OFF
SETLOCAL enabledelayedexpansion
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
SET /a $count=0
FOR %%a IN (q28850167*.txt) DO (
FOR /f "tokens=1,2*delims=: " %%b IN ('findstr /n /r "^" "%%a"') DO (
SET $%%b=!$%%b! %%d
IF !$count! LSS %%b SET /a $count=%%b
)
)
(
FOR /L %%a IN (1,1,%$count%) DO ECHO(!$%%a:~1!
)>newfile.txt
GOTO :EOF
我使用了包含您的数据的名为 q28850167*.txt
的文件进行测试。
产生 newfile.txt
清除所有从 $
对于匹配掩码的每个文件,通过 findstr/n
处理每一行以将 number :
应用到每一行的开头。 Select 第一列和第三列以上使用 :
和 Space 作为分隔符并附加到变量 $linenumber
跟踪最高行号在 $count
.
然后简单地从存储的数据中重现每一行。
以下所有解决方案都假设所有输入文件的格式一致且行数相同。
可以修改 Merge csv file side by side using batch file 中使用的技术来解析和支持 2 个以上的文件。我还在循环中打开和关闭延迟扩展,以保护可能出现在数据中的任何 !
。包含 !
的 FOR 变量如果在启用延迟扩展的情况下扩展,则会损坏:
@echo off
setlocal disableDelayedExpansion
3<"test2.txt" 4<"test3.txt" (
for /f "usebackq tokens=2 delims= " %%A in ("test1.txt") do (
set "A=%%A"
set /p "B=" <&3
set /p "C=" <&4
setlocal enableDelayedExpansion
echo !A! !B:* =! !C:* =!
endlocal
)
) >"result.txt"
使用 FOR 循环加上句柄 0 和 3-9,以上内容可以扩展为最多支持 9 个输入文件。如果输入超过 8 个,则需要多个循环。第一个循环可以处理前 9 个文件并将部分结果写入临时文件。连续循环可以从临时文件中读取并合并最多 8 个附加文件。
如果你的解析规则变得更复杂,上面的内容可能会变得很麻烦。
My JREPL.BAT hybrid JScript/batch utility 可用于高效解析和合并任意数量的文件,您可以根据需要修改正则表达式以解析几乎任何 csv 文件格式。
@echo off
setlocal
set "merge=jrepl ".*( .*)" "stdin.ReadLine()+" /j /f"
jrepl ".* (.*)" "" /f test1.txt | %merge% test2.txt | %merge% test3.txt >result.txt
理论上你可以使用任意数量的管道来支持你所有的输入文件,但如果你得到太多,它可能会变得低效。您可以使用临时文件暂存合并以保持效率。
最初在 this post 中描述的方法可以修改以处理可变数量的文件(最多 8 个),因此您只需将所需的文件放在参数中:
@echo off
setlocal DisableDelayedExpansion
rem MergeFiles.bat: Merge several files horizontally
rem Antonio Perez Ayala
rem Process files in the arguments and
rem assemble the lists of redirections and SET /P commands
set file1=%1
set "redirs="
set "commands="
set n=2
:nextFile
shift
if "%~1" equ "" goto endFiles
set /A n+=1
set "redirs=%redirs% %n%<%1"
set "commands=%commands% & set /P "part=!part:* =! " <&%n%"
goto nextFile
:endFiles
rem First file is read with FOR /F command
rem The rest of files are read via standard handles, starting at # 3
%redirs% (
for /F "usebackq delims=" %%a in (%file1%) do (
rem Get first part from first file
set "part=%%a"
rem Output parts from all files, excepting the last one
setlocal EnableDelayedExpansion
%commands:~3%
rem Output part from last file
echo !part:* =!
endlocal
)
) > result.txt
例如:
C:\> type file?.txt
file1.txt
A B
1 2
1 2
1 2
file2.txt
A C
1 3
1 3
1 3
fileX.txt
A X
1 x
1 x
1 x
fileY.txt
A Y
1 y
1 y
1 y
C:\> MergeFiles.bat file1.txt file2.txt fileX.txt fileY.txt
C:\> type result.txt
B C X Y
2 3 x y
2 3 x y
2 3 x y