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

У меня есть большой 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 в 13:31

3 ответа

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

sort -u input-file

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

sort -u input-file -o output-file

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

sort input-file | uniq > output-file

Мне нравится sort команда для подобных случаев, из-за ее простоты, но если Вы работаете с большими массивами awk подход из ответа 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

Другая значительная разница то, что упомянута @Ruslan:

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

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

enter image description here

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

for i in {1..500}; do cat /dev/urandom | tr -dc A-D | head -c 3; echo; done
11
ответ дан 7 January 2018 в 13:31
  • 1
    Добро пожаловать в AskUbuntu! Можно хотеть добавить дополнительную информацию так, чтобы исходный плакат знал что he' s выполнение при вводе тех строк кода в терминал. – Oyibo 3 October 2012 в 11:16
  • 2
    Добро пожаловать в AskUbuntu! Можно хотеть добавить дополнительную информацию так, чтобы исходный плакат знал что he' s выполнение при вводе тех строк кода в терминал. – Oyibo 3 October 2012 в 11:16

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

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

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

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

15
ответ дан 7 January 2018 в 13:31

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

datamash rmdup 1 < infile
1
ответ дан 7 January 2018 в 13:31
  • 1
    только начните - и оставьте пространство для создания его пунктом маркированного списка. – ish 3 June 2012 в 00:06
  • 2
    только начните - и оставьте пространство для создания его пунктом маркированного списка. – ish 3 June 2012 в 00:06

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

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