Перенаправить вывод канала в тот же файл

10

Есть ли короткий способ сохранить вывод канала в тот же файл, который он обрабатывает. Например, это то, что я на самом деле делаю

$ cat filename | sort | uniq > result
$ rm -f filename
$ mv result filename

Мне было интересно, есть ли способ сделать это только в одной строке (не добавляя эти команды с помощью & amp; & amp;)

Это не так, но чтобы получить представление

$ cat filename | sort | uniq > filename
    
задан whitenoisedb 26.09.2014 в 05:26
источник

5 ответов

14

Вы можете использовать sponge из moreutils пакета:

LC_ALL=C sort -u filename | sponge filename

Вам также не нужен канал для uniq , так как когда sort имеет -u для уникальных строк при сортировке.

Обратите внимание, что в системе GNU с локалями UTF-8 sort -u или sort | uniq не предоставили вам уникальные строки, а первые из последовательности строк, которые сортируют их в текущей локали.

$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=en_US.utf8 sort | LC_ALL=en_US.utf8 uniq
①

дал вам только . Изменение языкового стандарта на C приводит к упорядочению порядка сортировки на основе значений байтов:

$ export LC_ALL=C
$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=C sort | LC_ALL=C uniq
①
②
    
ответ дан cuonglm 26.09.2014 в 05:48
источник
10

Вам не нужна дополнительная команда, например cat и uniq , а также без использования команды rm и mv для удаления и переименования имени файла. просто используйте простую команду.

sort -u filename -o filename


 -u, --unique
        with -c, check for strict ordering; without -c, output only  the
        first of an equal run

 -o, --output=FILE
        write result to FILE instead of standard output

Как это работает?

Команда

sort сортирует ваше имя файла и с опцией -u , удаляет из нее повторяющиеся строки. затем с опцией -o записывает вывод в тот же файл с помощью метода на месте.

    
ответ дан αғsнιη 26.09.2014 в 06:10
3

Ваш предложенный пример (ниже) не работает, потому что вы действительно читаете и записываете один и тот же файл одновременно.

$ cat filename | sort | uniq > filename

Идея с трубкой или перенаправление заключается в том, что команда слева и справа от каждого канала или перенаправления запускается одновременно параллельно. Команда справа обрабатывает информацию, поскольку она передается ему из команды слева, а команда слева все еще работает.

Для того, чтобы ваш сценарий работал, команда, которая читает файл, должна завершиться до того, как начнется выполнение команды, которая начнет запись в файл. Чтобы это сработало, вам нужно сначала перенаправить вывод во временное местоположение, а затем, как только это будет завершено, отправьте его из временного местоположения обратно в файл.

Лучший способ сделать это в основном похож на ваш прежний пример, когда вы перенаправляете на временный файл, а затем переименуйте этот файл обратно в исходное (за исключением того, что вам не нужно сначала удалять файл, потому что перемещение удаляет любой существующая цель).

$ cat filename | sort | uniq > result
$ mv -f result filename

Вы также можете сохранить его в строковой переменной, за исключением того, что он работает только тогда, когда данные достаточно малы, чтобы сразу поместить их в память.

    
ответ дан thomasrutter 26.09.2014 в 05:50
1

Вы можете использовать команду tee :

sort -u filename | tee filename > /dev/null

Команда tee считывает со стандартного ввода и записывает в стандартные выходные файлы и .

    
ответ дан Sylvain Pineau 26.09.2014 в 07:11
0

Вы можете использовать Vim в режиме Ex:

ex -sc 'sort u|x' filename
  1. sort u sort unique

  2. x писать, если изменения были сделаны (они есть) и выйти

ответ дан Steven Penny 10.04.2016 в 22:55