Уникальная сортировка: перенаправление вывода в тот же файл

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

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

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

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

$ cat filename | sort | uniq > filename
1
задан 24 April 2018 в 12:06

4 ответа

Вам не нужна дополнительная команда, например 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 записывает вывод в тот же файл с помощью метода на месте.

11
ответ дан 24 May 2018 в 03:23
  • 1
    Если сбой системы при запуске sort, вы потеряете исходный файл. – cuonglm 26 September 2014 в 15:20
  • 2
    @Gnouc Итак, это конец неудачливым !! : '( – αғsнιη 26 September 2014 в 16:02
  • 3
    благодаря! в этом примере, в частности, я должен это сделать. Однако я думал об общем случае. @Gnouc, ха-ха, нет никакого способа думать, что если это не случится с тобой, верно? – whitenoisedb 27 September 2014 в 09:55

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

$ cat filename | sort | uniq > filename

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

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

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

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

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

3
ответ дан 24 May 2018 в 03:23
  • 1
    Поскольку кто-то потушен в предлагаемом редактировании, вы можете изменить cat filename | sort на просто sort filename - cat здесь не нужно. – thomasrutter 26 September 2014 в 10:58
  • 2
    Мой пример ниже - это не способ сделать это. Спасибо за разъяснение. cat может быть ненужным в этом случае, но я сосредоточился на части перенаправления. – whitenoisedb 26 September 2014 в 11:04
  • 3
    Я объяснял , почему ваш пример ниже не работает. Я знаю, что ты знал, что это не сработало. – thomasrutter 26 September 2014 в 11:05
  • 4
    Спасибо за разъяснения! На самом деле я не знал, что на самом деле происходит. – whitenoisedb 26 September 2014 в 11:08

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

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

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

1
ответ дан 24 May 2018 в 03:23
  • 1
    Это не работает для меня. – pjvandehaar 18 October 2015 в 08:40
  • 2
    Это не работает askubuntu.com/a/752451 – Steven Penny 11 April 2016 в 01:52
  • 3
    Это работает для меня. например, для перемещения строки в нижнюю часть файла: (cat ~/file | grep -v 3662 ; printentry 3662) | tee ~/file > /dev/null работает. Как и исходное сообщение, это не работает, если вы просто > ~/file без tee. Тив кажется похожим на sort -o file, который записывает в названный файл без продолжения того же самого канала. – Joshua Goldberg 3 April 2017 в 07:56
  • 4
    Подождите, извините! Я видел эмпирически, что это непредсказуемо потеряет данные, как объяснено в ссылке от @Steven. Сделайте файл с номерами 1..9 на 9 строках. Следующие действия будут работать несколько раз, а затем изредка удалять все данные из файла: (cat x | grep -v 7 ; echo 7) | tee x > /dev/null; cat x Я рекомендую временный файл и mv или, возможно, решение по ссылке @ Стивена. – Joshua Goldberg 20 April 2017 в 19:13
  • 5
    @JoshuaGoldberg вы видели мой ответ на этой странице? – Steven Penny 20 April 2017 в 19:20

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

ex -sc 'sort u|x' filename
sort u сортировать уникальные x записи, если изменения были сделаны (они есть) и выйти
0
ответ дан 24 May 2018 в 03:23

Другие вопросы по тегам:

Похожие вопросы: