テキスト ファイルから重複行を削除することはできますか? はいの場合、どのように?
8 に答える
確かに可能ですが、バッチを使用したほとんどのテキスト ファイル処理と同様に、きれいではなく、特に高速でもありません。
このソリューションは、重複を探すときに大文字と小文字を区別せず、行を並べ替えます。ファイルの名前は、最初の唯一の引数としてバッチ スクリプトに渡されます。
@echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "sorted=%file%.sorted"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^
::The 2 blank lines above are critical, do not remove
sort "%file%" >"%sorted%"
>"%deduped%" (
set "prev="
for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%sorted%") do (
set "ln=%%A"
setlocal enableDelayedExpansion
if /i "!ln!" neq "!prev!" (
endlocal
(echo %%A)
set "prev=%%A"
) else endlocal
)
)
>nul move /y "%deduped%" "%file%"
del "%sorted%"
このソリューションでは大文字と小文字が区別され、行は元の順序のままになります (もちろん重複を除く)。ここでも、ファイルの名前が最初の唯一の引数として渡されます。
@echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "line=%file%.line"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^
::The 2 blank lines above are critical, do not remove
>"%deduped%" (
for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file%") do (
set "ln=%%A"
setlocal enableDelayedExpansion
>"%line%" (echo !ln:\=\\!)
>nul findstr /xlg:"%line%" "%deduped%" || (echo !ln!)
endlocal
)
)
>nul move /y "%deduped%" "%file%"
2>nul del "%line%"
編集
上記の両方のソリューションは、空白行を削除します。個別の値について話すとき、空白行を保持する価値があるとは思いませんでした。
最初の文字が何であるかに関係なく、すべての非空白行が保持されるように、FOR /F "EOL" オプションを無効にするように両方のソリューションを変更しました。変更されたコードは、EOL オプションを改行文字に設定します。
新しいソリューション 2016 年 4 月 13 日: JSORT.BAT
私のJSORT.BAT ハイブリッド JScript/バッチ ユーティリティを使用して、単純な 1 つのライナー (および元のファイルを最終結果で上書きする MOVE) で効率的に並べ替えて重複行を削除できます。JSORT は、XP 以降のすべての Windows マシンでネイティブに実行される純粋なスクリプトです。
@jsort file.txt /u >file.txt.new
@move /y file.txt.new file.txt >nul
UnxUtils http://sourceforge.net/projects/unxutils/からhttp://en.wikipedia.org/wiki/Uniqを使用できますuniq
以下のバッチファイルは、あなたが望むことをします:
@echo off
setlocal EnableDelayedExpansion
set "prevLine="
for /F "delims=" %%a in (theFile.txt) do (
if "%%a" neq "!prevLine!" (
echo %%a
set "prevLine=%%a"
)
)
より効率的な方法が必要な場合は、フィルターuniq
として開発された、つまり Unixプログラムに似た、この Batch-JScript ハイブリッド スクリプトを試してください。次のように、.bat 拡張子を付けて保存しますuniq.bat
。
@if (@CodeSection == @Batch) @then
@CScript //nologo //E:JScript "%~F0" & goto :EOF
@end
var line, prevLine = "";
while ( ! WScript.Stdin.AtEndOfStream ) {
line = WScript.Stdin.ReadLine();
if ( line != prevLine ) {
WScript.Stdout.WriteLine(line);
prevLine = line;
}
}
両方のプログラムは、この投稿からコピーされました。
set "file=%CD%\%1"
sort "%file%">"%file%.sorted"
del /q "%file%"
FOR /F "tokens=*" %%A IN (%file%.sorted) DO (
SETLOCAL EnableDelayedExpansion
if not [%%A]==[!LN!] (
set "ln=%%A"
echo %%A>>"%file%"
)
)
ENDLOCAL
del /q "%file%.sorted"
これはまったく同じように機能するはずです。その dbenham の例は私には難しすぎるように思えたので、自分のソリューションをテストしました。使用例:filedup.cmd filename.ext
ピュアバッチ - 3 つの有効ライン。
@ECHO OFF
SETLOCAL
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
FOR /f "delims=" %%a IN (q34223624.txt) DO SET $%%a=Y
(FOR /F "delims=$=" %%a In ('set $ 2^>Nul') DO ECHO %%a)>u:\resultfile.txt
GOTO :EOF
バッチが機密性を持つ文字がデータに含まれていない場合は、問題なく動作します。
「q34223624.txt」は、質問 34223624 にこのデータが含まれていたためです。
1.1.1.1
1.1.1.1
1.1.1.1
1.2.1.2
1.2.1.2
1.2.1.2
1.3.1.3
1.3.1.3
1.3.1.3
それは完璧に機能します。