4

我有两个带有 5 个字段的 csv 文件,其中分隔符是逗号。我需要比较这些文件并获得一个输出文件,其中包含添加、更新或删除哪些行的信息。

我发现了几个使用 fc 或 comp 函数进行比较的批处理脚本,但只给出了文件之间的差异。我没有找到相关主题可以给出关于添加、更新或删除行的结果。

有人可以帮我吗?

4

2 回答 2

4

这个话题很有趣!也许你和我一样,对 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

安东尼奥

于 2012-11-09T04:46:13.880 回答
0

编辑:正如所指出的,这是一个 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))
于 2013-10-24T20:44:43.030 回答