Предлагаемый вами пример (ниже) не работает, потому что вы на самом деле читаете и пишете в один и тот же файл одновременно.
$ cat filename | sort | uniq > filename
Идея с каналом или перенаправлением состоит в том, что команда с левой и правой стороны каждого канала или перенаправления выполняется одновременно, параллельно. Команда справа обрабатывает информацию, передаваемую ей из команды слева, в то время как команда слева все еще выполняется.
Чтобы ваш сценарий работал, команда, которая читает из файла, должна завершиться до того, как начнется команда, которая записывает в файл. Для того, чтобы это работало, вам нужно сначала перенаправить вывод во временное местоположение, а затем, когда все будет готово, отправить его из временного местоположения обратно в файл.
Лучший способ сделать это, в основном, как в предыдущем примере, где вы перенаправляете во временный файл, а затем переименовываете этот файл обратно в исходный (за исключением того, что вам не нужно сначала удалять файл, потому что перемещение удаляет любую существующую цель) ,
$ cat filename | sort | uniq > result
$ mv -f result filename
Вы также можете сохранить его в строковую переменную, за исключением того, что он работает только тогда, когда данные достаточно малы, чтобы все сразу помещалось в память.
echo $(cat filename | sort | uniq > result) > filename
или что-то ? Просто проходя мимо, у меня нет времени, чтобы попробовать это.