-2

2 つのテキストファイルがありますが、それらを比較するにはどうすればよいですか?? 基本的に私が求めているのは、テキスト ファイル 1 から最初の行を取得し、それをテキスト ファイル 2 のすべての行と比較するものです。その行が表示されない場合は、その行をテキスト ファイル 3 に書き込みます。

次に、テキスト ファイル 1 の次の行を、テキスト ファイル 2 のすべての行と照合します。

4

1 に答える 1

1

Windows 用の grep のコピーがあれば、問題は簡単です。優れたフリー ソースの 1 つにGnuWinがあります。パッケージリンクから grep などの個々のユーティリティをダウンロードするか、[すべてダウンロード] リンクを使用して GnuWin スイート全体を取得できます(そのページの最初にあるダウンロード ボタンをクリックします)。

grep -v -x -F -f file2.txt file1.txt >file3.txt

-v= 一致ロジックを反転します - 一致しない行をリストします

-x= 行全体が正確に一致する必要があります

-F= 検索文字列は、正規表現ではなく文字列リテラルです

-f file1.txt= file1.txt から検索文字列を取得します


ネイティブの FINDSTR コマンドを使用してもほぼ同じことができますが、2 つの問題があります。

1)リテラル検索を指定する場合でも\、検索文字列内のバックスラッシュ文字は としてエスケープする必要があります。\\

2) 複数の大文字と小文字を区別するリテラル検索文字列が使用されている場合、いくつかの一致を見逃す原因となる厄介な FINDSTR バグがあります。

Windows FINDSTR コマンドの文書化されていない機能と制限事項は何ですか? を参照してください。文書化されていないFINDSTRの問題の「完全な」リストについては。

\以下は、大文字と小文字を区別しない検索を行うことが許容され、file2 に文字が含まれていない限り機能します。

findstr /x /v /i /l /g:file2.txt file1.txt >file3.txt

バックスラッシュの制限は、バックスラッシュをエスケープする一時ファイルを作成することで解消できます。これは少しのコードですが、最終結果は依然としてかなり高速に実行されます。検索では、大文字と小文字を区別しない必要があります。

@echo off
setlocal disableDelayedExpansion

::Define the files
set "file1=test1.txt"
set "file2=test2.txt"
set "file3=test3.txt"

::Create an LF variable containing a line feed character
set LF=^


::The above 2 blank lines are critical - do not remove

::Create a modified version of file2 that escapes any backslash
::EOL is set to a linefeed so that all non blank lines are preserved
::Delayed expansion is toggled on and off to protect ! characters
>"%file2%.mod" (
  for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file2%") do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    echo(!ln:\=\\!
    endlocal
  )
)

::Find lines in file1 that are missing from file2.mod
findstr /vixlg:"%file2%.mod" "%file1%" >"%file3%"

::Delete the temporary file2.mod
del "%file2%.mod"

2 つの FOR ループを使用して堅牢なネイティブ バッチ ソリューションを作成するのは比較的簡単ですが、ファイルが大きいとパフォーマンスが急速に低下します。

@echo off
setlocal disableDelayedExpansion

::Define the files
set "file1=test2.txt"
set "file2=test.txt"
set "file3=test3.txt"

::Create an LF variable containing a line feed character
set LF=^


::The above 2 blank lines are critical - do not remove

::Find lines in file1 that are missing from file2.mod
::EOL is set to a linefeed character so that all non blank lines are preserved
>"%file3%" (
  for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file1%") do (
    set "found="
    for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%B in ("%file2%") do (
      if %%A==%%B set found=1
    )
    if not defined found echo %%A
  )
)


シンプルで効率的なネイティブ PowerShell ソリューションがあるかもしれませんが、それは私の専門知識ではありません。

于 2012-09-10T17:13:33.260 に答える