Existe-t-il un Windows équivalent à l'Unix uniq?

17

J'ai besoin de supprimer les lignes en double d'un fichier texte, c'est simple sous Linux en utilisant

cat file.txt |sort | uniq

lorsque file.txt contient

aaa
bbb
aaa
ccc

Il produira

aaa
bbb
ccc

Existe-t-il un équivalent Windows? ou comment faire cela à la manière de Windows?

Yu Jiaao
la source
10
Sur Unix, vous pouvez l'écrire sous la formesort -u file.txt
jfs
1
Il y a aussi le WSL qui fonctionne plutôt bien pour ce genre de choses
user2813274
Peut-être que vous souhaitez définir quelque chose comme solution, si vous n'avez pas d'autres questions?
davidbaumann

Réponses:

31

L' Sort-Objectapplet de commande dans PowerShell prend en charge un -Uniquecommutateur qui fait la même chose que uniq:

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

Bien sûr, en raison de la présence d'alias dans PowerShell, vous pouvez également écrire:

type file.txt | sort -unique

De plus, il existe un /uniquecommutateur non documenté dans sort.exeWindows 10, donc cela devrait fonctionner dans l'invite de commandes:

type file.txt | sort /unique
Yu Jiaao
la source
1
Je ne pense pas que la commande Windows ( sort.exe) le supporte; il ressemble à une fonctionnalité du module intégré PowerShell.
Ben Voigt
1
type unsorted.txt | sort -unique> sorted.txt Cela fonctionne vraiment sous win10 et écrit des valeurs uniques dans un nouveau fichier
Lixas
7
@BenVoigt surprenante, type file.txt | sort /uniquefonctionne avec sans papier commutateur /uniqued' sort.exeutilité (au moins sous Windows 10). De l'autre côté, vous avez raison, l'exemple fourni est PowerShell Get-Content file.txt | Sort-Object -unique, en fait.
JosefZ
1
sort /uniquedes erreurs avec Invalid switch.sur Windows 7 Enterprise.
Don Cruickshank
1
@JosefZ, la réponse spécifie le commutateur en utilisant "/" (barre oblique) et non tiret; la barre oblique est la norme Windows pour les commandes en CMD, et toutes les commandes ne permettent pas de substituer un tiret à une barre oblique sur les commutateurs de commande. docs.microsoft.com/en-us/windows-server/administration/… pour une référence rapide affiche systématiquement des barres obliques. Ce qui précède était une excellente réponse, partageant une friandise peu connue, bien que je ne puisse pas imaginer pourquoi le commutateur "/ unique" n'est pas documenté car il est si utile.
Debra
6

Il existe des ports d'uniq qui fonctionnent de manière identique aux versions gnu / coreutils. Personnellement, j'utilise la variation de GOW, mais git pour Windows a une version considérablement plus récente . Aucun cygwin requis cependant pour ce dernier, vous devez regarder dans / usr / bin

Étant donné que ces packages contiennent également cat, sort et uniq - votre flux de travail doit être essentiellement identique et cat file.txt |sort | uniqfonctionner principalement de manière identique

Compagnon Geek
la source
2

Vous pouvez facilement écrire vous-même la commande "uniq". Enregistrez-le dans un fichier batch "uniq.cmd" quelque part dans votre% path% peut le trouver (par exemple dans% windir% \ system32). Cette version n'est PAS sensible à la casse:

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

Cela fonctionne avec "uniq mytextfile" ainsi qu'avec "cat mytextfile | uniq"; car toutes les entrées et tous les arguments sont simplement passés à la commande sort.

À partir de Windows 7, vous voudrez peut-être une version vraiment sensible à la casse (la différence est le commutateur non documenté "sort / C" et non "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
la source
Sympa, mais il a quelques défauts. Il ne actuellement avec comme contenu /?, ON, one ^ caretou bang!. Mais cela peut être résolu en utilisant la technique d'expansion retardée à bascule et echo(voir: Dostips: ECHO. ÉCHEC de donner un texte ou une ligne vierge
jeb
Merci, la raison de l'utilisation de la technique d'extension retardée n'était pas évidente ni marquée. J'ai édité mes exemples pour qu'ils soient (presque) parfaits maintenant.
Tom Stein
0

Ajout à la réponse de Yu Jiaao. Vous pouvez appeler l' sort-objectapplet de commande powershell dans une invite de commande comme:

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