sort 管道传输到 uniq 如何在 unix 中工作

How sort piped into uniq works in unix

在以下:

cat file | cut -f 1,5,6 | sort | uniq

我直觉认为 uniq 在继续之前需要知道整个数据集。
HERE 我了解到 sort 确实 将临时文件写入磁盘以获取长数据集。

是否uniq 将临时文件写入磁盘以获取长数据集?在哪里?

谢谢!

uniq只需要一次读取一行,并将当前行与上一行进行比较;它可以在开始排队时立即开始工作;在产生任何输出之前无需读取所有输入。

基本上,它只需要读取一行,并将其与上一行进行比较。如果它们相同,则增加一个计数器。如果不是,则打印上一行(如果需要,则使用计数)。然后将当前行保存为上一行,并重复。

这是一个用 C 编写的基本版本,您可以将其用作示例:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
  _Bool show_count = 0;

  if (argc == 2 && strcmp(argv[1], "-c") == 0) {
    show_count = 1;
  } else if (argc > 1) {
    fprintf(stderr, "Usage: %s [-c]\n", argv[0]);
    return EXIT_FAILURE;
  }

  char *prev = NULL;
  size_t prev_len = 0;
  int count = 1;
  while (1) {
    char *line = NULL;
    size_t line_len = 0;
    ssize_t len = getline(&line, &line_len, stdin);
    if (len < 0) {
      if (feof(stdin)) {
        break;
      } else {
        fprintf(stderr, "Couldn't read input: %s\n", strerror(errno));
        return EXIT_FAILURE;
      }
    } else {
      if (prev) {
        if (strcmp(line, prev) == 0) {
          count++;
        } else {
          if (show_count) {
            printf("%7d ", count);
          }
          fwrite(prev, 1, prev_len, stdout);
          count = 1;
        }
        free(prev);
      }
    }
    prev = line;
    prev_len = len;
  }

  if (prev) {
    if (show_count) {
      printf("%7d ", count);
    }
    fwrite(prev, 1, prev_len, stdout);
    free(prev);
  }

  return 0;
}