我有两个带有 5 个字段的 csv 文件,其中分隔符是逗号。我需要比较这些文件并获得一个输出文件,其中包含添加、更新或删除哪些行的信息。
我发现了几个使用 fc 或 comp 函数进行比较的批处理脚本,但只给出了文件之间的差异。我没有找到相关主题可以给出关于添加、更新或删除行的结果。
有人可以帮我吗?
我有两个带有 5 个字段的 csv 文件,其中分隔符是逗号。我需要比较这些文件并获得一个输出文件,其中包含添加、更新或删除哪些行的信息。
我发现了几个使用 fc 或 comp 函数进行比较的批处理脚本,但只给出了文件之间的差异。我没有找到相关主题可以给出关于添加、更新或删除行的结果。
有人可以帮我吗?
这个话题很有趣!也许你和我一样,对 FC 命令的输出格式感到困惑和恼火,尽管它确实提供了所需的信息。下面的批处理程序获取 FC 命令的输出并重新排列它,以允许识别是否在原始文件的两行之间添加了新的信息块,或者是否从原始文件中删除了行块,或任何其他文件修改情况(更新)。最困难的部分是选择格式以令人愉快的方式显示信息,但我认为我的解决方案非常好!
@echo off
rem FCOMP.BAT: Format FC output in a pleasant way
rem Antonio Perez Ayala
if "%~2" neq "" goto start
echo Format FC output identifying added, deleted or updated sections
echo/
echo FCOMP filename1 filename2 [/switches /for /FC /command]
goto :EOF
:start
setlocal EnableDelayedExpansion
set while=if not
set do=goto endwhile
set endwhile=goto while
set "space= "
set "spaces39= "
fc %3 %4 %5 %6 %7 %8 %9 %1 %2 > differences.txt
if %errorlevel% equ 1 call :FormatFC < differences.txt
del differences.txt
goto :EOF
:FormatFC
set /P line=
set /P line=
rem Process each set of differences
:while
%while% defined line %do%
rem Load old and new sections of this set
set line=
set /P line=
set old=0
:while1
%while% "!line:~0,5!" neq "*****" %do%1
set /A old+=1
set oldLine[%old%]=!line!%spaces39%
set line=
set /P line=
%endwhile%1
:endwhile1
set line=
set /P line=
set new=0
:while2
%while% "!line:~0,5!" neq "*****" %do%2
set /A new+=1
set newLine[%new%]=!line!%space%
set line=
set /P line=
%endwhile%2
:endwhile2
rem Identify the type of this set
if %old% equ 2 (
echo ====== NEW SECTION ADDED ====================================================
echo/
echo(!oldLine[1]:~0,79!
set /A new-=1
for /L %%i in (2,1,!new!) do echo( ^|!newLine[%%i]:~0,70!
echo(!oldLine[2]:~0,79!
) else if %new% equ 2 (
echo OLD SECTION DELETED ==========================================================
echo/
echo(---------!newLine[1]:~0,70!
set /A old-=1
for /L %%i in (2,1,!old!) do echo -!oldLine[%%i]:~0,78!
echo(---------!newLine[2]:~0,70!
) else ( rem both %old% and %new% gtr 2
echo ============================== SECTION UPDATED ==============================
echo/
if %old% lss %new% (
for /L %%i in (1,1,%old%) do echo(!oldLine[%%i]:~0,39!^|!newLine[%%i]:~0,39!
set /A old+=1
for /L %%i in (!old!,1,%new%) do echo(%spaces39%^|!newLine[%%i]:~0,39!
) else (
for /L %%i in (1,1,%new%) do echo(!oldLine[%%i]:~0,39!^|!newLine[%%i]:~0,39!
set /A new+=1
for /L %%i in (!new!,1,%old%) do echo(!oldLine[%%i]:~0,39!
)
)
rem Pass to next set of differences
echo/
set /P line=
set line=
set /P line=
%endwhile%
:endwhile
exit /B
安东尼奥
编辑:正如所指出的,这是一个 shell 脚本选项,希望它可以对其他人有所帮助
这是一个选项,我没有检查过大文件的性能:
$ cat file1
1,'adam'
2,'chris'
6,'phil'
3,'charles'
$ cat file2
2,'christopher'
6,'phil'
3,'chuck'
8,'sue',2
4,'mary'
21,'matt'
--我们假设 CSV 文件分隔符是逗号,每条记录的第一个字段是主键(唯一值)
$ comm -3 <(sort file1) <(sort file2) | sed -e 's/^[ \t]*//' | awk -F , '{if (a[$1]) {print "^"$1","} {a[$1] = $0}}' > data2.txt
- 更新
$ cat data2.txt | grep -E -f - file2
--删除
$ cat data2.txt | grep -v -E -f - <(comm -2 -3 <(sort file1) <(sort file2))
--插入
$ cat data2.txt | grep -v -E -f - <(comm -1 -3 <(sort file1) <(sort file2))