¿Hay un Windows equivalente al Unix uniq?

17

Necesito eliminar líneas duplicadas de un archivo de texto, es simple en Linux usando

cat file.txt |sort | uniq

cuando file.txt contiene

aaa
bbb
aaa
ccc

Saldrá

aaa
bbb
ccc

¿Hay un equivalente de Windows? o cómo hacer esto de una manera Windows?

Yu Jiaao
fuente
10
En Unix, puedes escribirlo comosort -u file.txt
jfs
1
También hay WSL que funciona bastante bien en lo que respecta a este tipo de cosas
usuario2813274
¿Quizás desee establecer algo como solución, si no tiene más preguntas?
davidbaumann

Respuestas:

31

El Sort-Objectcmdlet en PowerShell admite un -Uniqueconmutador que hace lo mismo que uniq:

Get-Content file.txt | Sort-Object -unique

Por supuesto, debido a la presencia de alias en PowerShell, también puede escribir:

type file.txt | sort -unique

Además, hay un /uniqueinterruptor no documentado en sort.exeWindows 10, por lo que esto debería funcionar en el símbolo del sistema:

type file.txt | sort /unique
Yu Jiaao
fuente
1
No creo que el comando de Windows ( sort.exe) sea compatible con esto; parece una característica de la construcción incorporada de PowerShell.
Ben Voigt
1
escriba unsorted.txt | sort -unique> sorted.txt Esto realmente funciona bajo win10 y escribió valores únicos para el nuevo archivo
Lixas
77
@BenVoigt sorprendentemente, type file.txt | sort /uniquefunciona con indocumentado interruptor /uniquede sort.exeutilidad (por lo menos en Windows 10). Por otro lado, tiene razón en que el ejemplo proporcionado es PowerShell Get-Content file.txt | Sort-Object -unique, de hecho.
JosefZ
1
sort /uniqueerrores con Invalid switch.en Windows 7 Enterprise.
Don Cruickshank el
1
@JosefZ, la respuesta especifica el cambio usando "/" (barra diagonal) y no guión; la barra diagonal es el estándar de Windows para los comandos en CMD, y no todos los comandos permiten sustituir una barra por una barra en los interruptores de comando. docs.microsoft.com/en-us/windows-server/administration/… para una referencia rápida muestra barras inclinadas consistentemente. Lo anterior fue una gran respuesta, compartir un tidbit no conocido comúnmente, aunque no puedo imaginar por qué el interruptor "/ unique" no está documentado, ya que es muy útil.
Debra
6

Hay puertos de uniq que funcionan de manera idéntica a las versiones gnu / coreutils. Personalmente uso la variación de GOW, pero git para Windows tiene una versión significativamente más nueva . No se requiere cygwin, pero para esto último debe buscar en / usr / bin

Dado que estos paquetes también contienen cat, sort y uniq, su flujo de trabajo debería ser en su mayoría idéntico, y cat file.txt |sort | uniqdebería funcionar de manera idéntica

Journeyman Geek
fuente
2

Puede escribir fácilmente el comando "uniq" usted mismo. Guarde esto en un archivo por lotes "uniq.cmd" en algún lugar de su% path% puede encontrarlo (por ejemplo, en% windir% \ system32). Esta versión NO distingue entre mayúsculas y minúsculas:

@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
)

Esto funciona con "uniq mytextfile" y "cat mytextfile | uniq"; ya que todas las entradas y argumentos simplemente se pasan al comando de clasificación.

A partir de Windows 7, es posible que desee una versión realmente sensible a mayúsculas y minúsculas (la diferencia es que el interruptor no documentado "sort / C" y 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
)
Tom Stein
fuente
Agradable, pero tiene algunos defectos. En la actualidad produce un error con el contenido como /?, ON, one ^ careto bang!. Pero eso se puede resolver mediante el uso de la técnica de alternancia de expansión retardada y echo(ver: Dostips: ECHO. FALLA en dar texto o línea en blanco
jeb
Gracias, la razón para usar la técnica de expansión retardada de alternancia no había sido obvia ni marcada. Edité mis ejemplos para que sean (casi) perfectos ahora.
Tom Stein
0

Además de la respuesta de Yu Jiaao. Puede invocar el sort-objectcmdlet powershell en un símbolo del sistema como:

type file.txt | powershell -nop "$input | sort -unique"
snipsnipsnip
fuente