Con GNU sort
e una shell in cui printf
è incorporato (tutti quelli simili a POSIX al giorno d'oggi tranne alcune varianti di pdksh
):
printf '%s\0' * | sort -u --files0-from=- > output
Ora, un problema è che, poiché i due componenti di quella pipeline vengono eseguiti contemporaneamente e indipendentemente, quando quello sinistro espande il *
glob, quello destro potrebbe aver output
già creato il file che potrebbe causare problemi (forse non con -u
qui) come output
sarebbe sia un file di input che di output, quindi potresti voler fare in modo che l'output vada in un'altra directory ( > ../output
per esempio), o assicurati che il glob non corrisponda al file di output.
Un altro modo per affrontarlo in questo caso è scriverlo:
printf '%s\0' * | sort -u --files0-from=- -o output
In questo modo, si sta sort
aprendo output
per la scrittura e (nei miei test), non lo farà prima di aver ricevuto l'elenco completo dei file (molto tempo dopo l'espansione del glob). Eviterà anche di bloccare output
se nessuno dei file di input è leggibile.
Un altro modo di scriverlo con zsh
obash
sort -u --files0-from=<(printf '%s\0' *) -o output
Sta usando la sostituzione del processo (dove <(...)
viene sostituito da un percorso di file che si riferisce all'estremità di lettura della pipe su cui printf
sta scrivendo). Questa funzione viene ksh
, ma ksh
insiste nel fare l'espansione di <(...)
un argomento separato al comando in modo da non poterlo usare con la --option=<(...)
sintassi. Funzionerebbe con questa sintassi però:
sort -u --files0-from <(printf '%s\0' *) -o output
Nota che vedrai una differenza dagli approcci che alimentano l'output dei cat
file nei casi in cui ci sono file che non finiscono con un carattere di nuova riga:
$ printf a > a
$ printf b > b
$ printf '%s\0' a b | sort -u --files0-from=-
a
b
$ printf '%s\0' a b | xargs -r0 cat | sort -u
ab
Si noti inoltre che sort
ordina utilizzando l'algoritmo di confronto nelle impostazioni locali ( strcollate()
) e sort -u
riporta una di ciascuna serie di righe che ordinano lo stesso in base all'algoritmo, non linee univoche a livello di byte. Se ti interessa solo che le linee siano univoche a livello di byte e non ti interessi così tanto all'ordine in cui sono ordinate, potresti voler correggere le impostazioni locali su C dove l'ordinamento si basa su valori di byte ( memcmp()
; questo probabilmente accelererebbe le cose in modo significativo):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
sort
lo fa automaticamente per l'immissione di più file .. ma poisort -u *
fallirei anche conArgument list too long
suppongo