Seu exemplo sugerido (abaixo) não funciona porque você realmente está lendo e gravando no mesmo arquivo simultaneamente.
$ cat filename | sort | uniq > filename
A idéia com um canal ou redirecionamento é que o comando no lado esquerdo e direito de cada canal ou redirecionamento seja executado simultaneamente, em paralelo. O comando à direita processa as informações conforme são entregues a partir do comando à esquerda, enquanto o comando à esquerda ainda está em execução.
Para que seu cenário funcione, o comando que lê do arquivo precisaria ser concluído antes que o comando que grava no arquivo seja iniciado. Para que isso funcione, você precisará redirecionar a saída para um local temporário primeiro e, depois que terminar, envie-o do local temporário de volta para o arquivo.
Uma maneira melhor de fazer isso é basicamente como no exemplo anterior, em que você redireciona para um arquivo temporário e depois renomeia esse arquivo para o original (exceto que você não precisa excluir o arquivo primeiro, porque a movimentação exclui qualquer destino existente) .
$ cat filename | sort | uniq > result
$ mv -f result filename
Você também pode salvá-lo em uma variável de sequência, exceto que só funciona quando os dados são pequenos o suficiente para caberem na memória de uma só vez.
echo $(cat filename | sort | uniq > result) > filenameou alguma coisa ? Só de passagem, não tenho tempo para tentar.