I need remove duplicate lines from a text file, it is simple in Linux using
cat file.txt |sort | uniq
when file.txt contains
aaa
bbb
aaa
ccc
It will output
aaa
bbb
ccc
Is there a Windows equivalent? or how do this in a Windows way?
Super User is a question and answer site for computer enthusiasts and power users. It only takes a minute to sign up.
Sign up to join this communityThe Sort-Object
cmdlet in PowerShell supports a -Unique
switch that does the same thing as uniq
:
Get-Content file.txt | Sort-Object -unique
Of course, owing to presence of aliases in PowerShell, you can also write:
type file.txt | sort -unique
Additionally, there is an undocumented /unique
switch in sort.exe
of Windows 10, so, this should work in Command Prompt:
type file.txt | sort /unique
sort.exe
) supports this; it looks like a feature of the PowerShell builtin.
Apr 23, 2018 at 4:11
type file.txt | sort /unique
works with undocumented switch /unique
of sort.exe
utility (at least on Windows 10). On the other side, you are right that provided example is PowerShell Get-Content file.txt | Sort-Object -unique
, in fact.
sort /unique
errors with Invalid switch.
on Windows 7 Enterprise.
Apr 23, 2018 at 12:00
There's ports of uniq that work identically to the gnu/coreutils versions. I personally use the variation from GOW but git for windows has a significantly newer version. No cygwin required though for the latter you need to look in /usr/bin
Since these packages also contain cat, sort and uniq - your workflow should be mostly identical, and cat file.txt |sort | uniq
should work mostly identically
You can easily write the command "uniq" by yourself. Save this in a batch file "uniq.cmd" somewhere in your %path% can find it (e.g. in %windir%\system32). This version is NOT case sensitive:
@echo off
setlocal DisableDelayedExpansion
set "prev="
for /f "delims=" %%F in ('sort %*') do (
rem "set" needs to be done without delayed expansion
set "line=%%F"
setlocal EnableDelayedExpansion
set "line=!line:<=<!"
if /i "!prev!" neq "!line!" echo(!line!
set "prev=!line!"
endlocal
)
This works with "uniq mytextfile" as well as "cat mytextfile | uniq"; as all input and arguments are simply passed to the sort command.
Starting with Windows 7, you may want a really case sensitive version (the difference ist undocumented switch "sort /C" and no "if /i"):
@echo off
setlocal DisableDelayedExpansion
set "prev="
for /f "delims=" %%F in ('sort /C %*') do (
rem "set" needs to be done without delayed expansion
set "line=%%F"
setlocal EnableDelayedExpansion
set "line=!line:<=<!"
if "!prev!" neq "!line!" echo(!line!
set "prev=!line!"
endlocal
)
/?
, ON
, one ^ caret
or bang!
. But that can be solved by using the toggling delayed expansion technic and echo(
see: Dostips: ECHO. FAILS to give text or blank line
Addition to Yu Jiaao's answer. You can invoke the sort-object
powershell cmdlet in a command prompt like:
type file.txt | powershell -nop "$input | sort -unique"
sort -u file.txt