Команда, которая будет печатать только одно значение, хотя оно появляется много раз

У меня есть большой файл txt, значения которого повторяются много раз. Есть ли какая-нибудь команда, которую я могу использовать, которая будет проходить через файл, и если одно значение появится однажды, не повторите его снова?

SO4 HOH CL BME HOH SO4 HOH CL BME HOH SO4 HOH SO4 HOH CL BME HOH SO4 HOH CL BME HOH CL

Поэтому он должен выглядеть примерно так:

S04 HOH CL BME

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

8
задан 7 January 2018 в 14:31

9 ответов

Вы можете использовать команду sort с опцией --unique:

sort -u input-file

Если вы хотите записать результат в FILE вместо стандартного вывода, используйте опцию --output=FILE:

sort -u input-file -o output-file

Также может быть применена команда uniq. В этом случае идентичные строки должны быть косвенными, поэтому вход должен быть отсортирован предварительно - благодаря @RonJohn для этой заметки:

sort input-file | uniq > output-file

Мне нравится команда sort для подобных случаев, из-за его простоты, но если вы работаете с большими массивами, то подход awk от [10] от [10] @RonJohn от John1024 может быть более мощным. Ниже приведено сравнение времени между упомянутыми подходами, применяемыми к файлу (на основе приведенного выше примера) с почти 5 миллионами строк:

$ cat input-file | wc -l
20000000

$ TIMEFORMAT=%R
$ time sort -u input-file | wc -l
64
7.495

$ time sort input-file | uniq | wc -l
64
7.703

$ time awk '!a[$0]++' input-file | wc -l      # from John1024's answer
64
1.271

$ time datamash rmdup 1 < input-file | wc -l  # from αғsнιη's answer
64
0.770

Другое существенное различие заключается в том, что упомянутый этот :

sort -u будет печатать результат только после завершения ввода, тогда как эта команда awk будет печатать каждую новую строку результатов «на лету» (это может быть более важно для ввода в канал, чем файл).

Вот иллюстрация:

, что

В приведенном выше примере цикл (показан ниже) генерирует 500 случайных комбинаций, каждая с длиной в три символа, буквы AD. Эти комбинации подаются на канал awk или sort.

for i in {1..500}; do cat /dev/urandom | tr -dc A-D | head -c 3; echo; done
11
ответ дан 22 May 2018 в 15:43
  • 1
    Это очень простая команда! Большое спасибо! Всего наилучшего. – djordje 6 January 2018 в 12:42
  • 2
    О, в те дни, когда одна утилита делала одно и делала это хорошо! [F1] !!!! – RonJohn 7 January 2018 в 05:33

Вы можете использовать команду sort с опцией --unique:

sort -u input-file

Если вы хотите записать результат в FILE вместо стандартного вывода, используйте опцию --output=FILE:

sort -u input-file -o output-file

Также может быть применена команда uniq. В этом случае идентичные строки должны быть косвенными, поэтому вход должен быть отсортирован предварительно - благодаря @RonJohn для этой заметки:

sort input-file | uniq > output-file

Мне нравится команда sort для подобных случаев, из-за его простоты, но если вы работаете с большими массивами, то подход awk от [10] от [10] @RonJohn от John1024 может быть более мощным. Ниже приведено сравнение времени между упомянутыми подходами, применяемыми к файлу (на основе приведенного выше примера) с почти 5 миллионами строк:

$ cat input-file | wc -l 20000000 $ TIMEFORMAT=%R $ time sort -u input-file | wc -l 64 7.495 $ time sort input-file | uniq | wc -l 64 7.703 $ time awk '!a[$0]++' input-file | wc -l # from John1024's answer 64 1.271 $ time datamash rmdup 1 < input-file | wc -l # from αғsнιη's answer 64 0.770

Другое существенное различие заключается в том, что упомянутый этот :

sort -u будет печатать результат только после завершения ввода, тогда как эта команда awk будет печатать каждую новую строку результатов «на лету» (это может быть более важно для ввода в канал, чем файл).

Вот иллюстрация:

, что

В приведенном выше примере цикл (показан ниже) генерирует 500 случайных комбинаций, каждая с длиной в три символа, буквы AD. Эти комбинации подаются на канал awk или sort.

for i in {1..500}; do cat /dev/urandom | tr -dc A-D | head -c 3; echo; done
11
ответ дан 17 July 2018 в 23:45

Вы можете использовать команду sort с опцией --unique:

sort -u input-file

Если вы хотите записать результат в FILE вместо стандартного вывода, используйте опцию --output=FILE:

sort -u input-file -o output-file

Также может быть применена команда uniq. В этом случае идентичные строки должны быть косвенными, поэтому вход должен быть отсортирован предварительно - благодаря @RonJohn для этой заметки:

sort input-file | uniq > output-file

Мне нравится команда sort для подобных случаев, из-за его простоты, но если вы работаете с большими массивами, то подход awk от [10] от [10] @RonJohn от John1024 может быть более мощным. Ниже приведено сравнение времени между упомянутыми подходами, применяемыми к файлу (на основе приведенного выше примера) с почти 5 миллионами строк:

$ cat input-file | wc -l 20000000 $ TIMEFORMAT=%R $ time sort -u input-file | wc -l 64 7.495 $ time sort input-file | uniq | wc -l 64 7.703 $ time awk '!a[$0]++' input-file | wc -l # from John1024's answer 64 1.271 $ time datamash rmdup 1 < input-file | wc -l # from αғsнιη's answer 64 0.770

Другое существенное различие заключается в том, что упомянутый этот :

sort -u будет печатать результат только после завершения ввода, тогда как эта команда awk будет печатать каждую новую строку результатов «на лету» (это может быть более важно для ввода в канал, чем файл).

Вот иллюстрация:

, что

В приведенном выше примере цикл (показан ниже) генерирует 500 случайных комбинаций, каждая с длиной в три символа, буквы AD. Эти комбинации подаются на канал awk или sort.

for i in {1..500}; do cat /dev/urandom | tr -dc A-D | head -c 3; echo; done
11
ответ дан 24 July 2018 в 17:05

Если вы хотите сохранить выходные строки в том же порядке, что и входные, используйте:

$ awk '!a[$0]++' file
SO4
HOH
CL
BME

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

В этом случае используется ассоциативный массив a чтобы подсчитать количество раз, когда была просмотрена каждая строка. Если он еще не был замечен, строка печатается.

15
ответ дан 22 May 2018 в 15:43
  • 1
    Это работает. Благодаря! Всего наилучшего – djordje 6 January 2018 в 12:41
  • 2
    Это очень сложно с awk, но sort -u - простой способ. – Pierre François 6 January 2018 в 13:36
  • 3
    @ PierreFrançois, но sort -u также является самым медленным способом :) Я обновил свой ответ с помощью сравнения времени между двумя подходами. – pa4080 6 January 2018 в 14:47
  • 4
    Кроме того, sort -u будет распечатывать результат только после завершения ввода, в то время как эта команда awk будет печатать каждую новую строку результатов «на лету» (это может быть более важно для ввода в канал, кроме файла). – Ruslan 7 January 2018 в 01:03
  • 5
    Спасибо за эту заметку @Ruslan! Я попытался проиллюстрировать это в своем ответе. – pa4080 7 January 2018 в 14:27

Вы можете использовать GNU datamash здесь также следующим образом и сохраните порядок строк.

datamash rmdup 1 < infile
1
ответ дан 22 May 2018 в 15:43

Если вы хотите сохранить выходные строки в том же порядке, что и входные, используйте:

$ awk '!a[$0]++' file SO4 HOH CL BME

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

В этом случае используется ассоциативный массив a чтобы подсчитать количество раз, когда была просмотрена каждая строка. Если он еще не был замечен, строка печатается.

15
ответ дан 17 July 2018 в 23:45

Вы можете использовать GNU datamash здесь также следующим образом и сохраните порядок строк.

datamash rmdup 1 < infile
1
ответ дан 17 July 2018 в 23:45

Если вы хотите сохранить выходные строки в том же порядке, что и входные, используйте:

$ awk '!a[$0]++' file SO4 HOH CL BME

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

В этом случае используется ассоциативный массив a чтобы подсчитать количество раз, когда была просмотрена каждая строка. Если он еще не был замечен, строка печатается.

15
ответ дан 24 July 2018 в 17:05
  • 1
    Это работает. Благодаря! Всего наилучшего – djordje 6 January 2018 в 12:41
  • 2
    Это очень сложно с awk, но sort -u - простой способ. – Pierre François 6 January 2018 в 13:36
  • 3
    @ PierreFrançois, но sort -u также является самым медленным способом :) Я обновил свой ответ с помощью сравнения времени между двумя подходами. – pa4080 6 January 2018 в 14:47
  • 4
    Кроме того, sort -u будет распечатывать результат только после завершения ввода, в то время как эта команда awk будет печатать каждую новую строку результатов «на лету» (это может быть более важно для ввода в канал, кроме файла). – Ruslan 7 January 2018 в 01:03
  • 5
    Спасибо за эту заметку @Ruslan! Я попытался проиллюстрировать это в своем ответе. – pa4080 7 January 2018 в 14:27

Вы можете использовать GNU datamash здесь также следующим образом и сохраните порядок строк.

datamash rmdup 1 < infile
1
ответ дан 24 July 2018 в 17:05

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

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