仅基于 column1 的 Findstr [批处理文件]

Findstr based on column1 only [batch file]

我一直在通过 Whosebug 进行搜索,但找不到符合要求的答案。我有 2 个 .txt 个文件要比较,return 个存在差异的第 3 个文件。

但是,只有前 2 个文件的第一列需要比较。

E:\Compare_flie\file_1.txt

GND ZERO
22XC44    XXYYZZ
33XC55    YYUUTT

E:\Compare_file\file_2.txt

GND ZERO
22XC44    KK77UU
33XC55    88JJ66
66NN77    HHOO99
99CC88    UU77RR

E:\Compare_file\file_3.txt(预期输出)

66NN77    HH0099
99CC88    UU77RR

尝试了下面的代码,但它只擅长找出行中所有字符串的差异

%echo on
findstr /v /i /g:E:\Compare_files\file_1.txt E:\Compare_files\file_2.txt 
> E:\Compare_files\file_3.txt

进一步完善,但还没有达到目标。

%echo on
for /f "tokens=1 delims= " %%I in ("E:\Compare_files\file_1.txt") do 
findstr /v /i "%%I"/g:"D:\Compare_files\file_2.txt" 
> "D:\Compare_files\file_3.txt"

如果有人能提供帮助,我们将不胜感激。

这是一种使用批处理和 type command piping the first file's contents over to the findstr 命令然后相应地传递参数以将这些结果重定向到临时文件的方法。

使用 for /f loop with "usebackq tokens=1 delims= " it will iterate through the temp file and for each line in that file parsing accordingly, it will append the column one lines with an echo command using >> to redirect 结果达到 file_3.txt 的预期结果。

请注意添加 if exist "%srcdir%\file_3.txt" del /q /f "%srcdir%\file_3.txt" 以删除该文件(如果存在),因为 for /f echo 命令将一个接一个地附加到它。

@echo on
set srcdir=E:\Compare_files
set tmpfile=%temp%\%~N0.tmp

type "%srcdir%\file_1.txt" | findstr /vig:"%srcdir%\file_2.txt">"%tmpfile%"

if exist "%srcdir%\file_3.txt" del /q /f "%srcdir%\file_3.txt"
for /f "usebackq tokens=1 delims= " %%I in ("%tmpfile%") do (
    echo %%~I>>"%srcdir%\file_3.txt"
)

更多资源

  • FOR /F
  • FOR /?

        usebackq        - specifies that the new semantics are in force,
                          where a back quoted string is executed as a
                          command and a single quoted string is a
                          literal string command and allows the use of
                          double quotes to quote file names in
                          file-set.
    
  • Redirection

  • Comparing/finding the difference between two text files using findstr

据我了解你的问题,你想要来自 file_2.txt 的行,其第一列不包含在 file_1.txt 的第一列中,即:file_2.txt minus file_1.txt。有一种更简单的方法可以得到这样的结果:

@echo off
setlocal

rem Fill "line" array with lines from file_2.txt
rem use the first column for the array keys
for /F "delims=" %%a in (file_2.txt) do for /F %%b in ("%%a") do set "line[%%b]=%%a"

rem Delete array elements with same key from file_1.txt
for /F %%b in (file_1.txt) do set "line[%%b]="

rem Show remaining elements
(for /F "tokens=1* delims==" %%a in ('set line[') do echo %%b) > file_3.txt
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q48816766.txt"
SET "filename2=%sourcedir%\q48816766_2.txt"
SET "tempfile=%temp%\q48816766.tmp"
SET "outfile=%destdir%\outfile.txt"
(FOR /f "usebackq" %%a IN ("%filename1%") DO ECHO %%a )>"%tempfile%"
FINDSTR /b /v /g:"%tempfile%" "%filename2%">"%outfile%"
REM DEL "%tempfile%" /F /Q

GOTO :EOF

我已经设置了适合我的系统的名称,但是这两个文件包含您的数据。

显然,只有在引用文件名时才需要 for/f 上的 usebackq。命令两边的括号允许将 echoed 输出累积到临时文件中。这里重要的是 %%a) 之间的 space。这确保临时文件包含尾随 spaces.

然后通过 /g 将临时文件应用到第二个数据文件,就像在 OP 的代码中一样。临时文件中尾随 space 的存在确保唯一选择省略的行是第一列完全匹配的行,例如 66NN7 出现在第一个文件、第一列,然后是这个不会匹配第二个文件中的66NN77