cshelluniq

Implementing custom uniq in linux shell development


I'm developing a custom shell. In this assignment, I need to implement uniq-like command. Given sorted lines, uniq should be able to print all unique values and (their number of occurences if the command is uniq -c). Example code is stated at the very end.

I have no problem with the algorithm. I wrote a function which can do take exactly same operation with desired one. However, the problem is that, what are these types of outputs and inputs? I mean when I command cat input.txt, are these lines just one string or are they given in array? As I said, algorithm is ok but I do not know how to apply that correct algorithm in the shell? Any help or idea is appreciated.

$cat input.txt
Cinnamon
Egg
Egg
Flour
Flour
Flour
Milk
Milk
$cat input.txt | uniq
Cinnamon
Egg
Flour
Milk

Solution

  • are these lines just one string or are they given in array

    These lines are the result of a fork, just strings that have been sent to stdout.

    getline is very useful in these cases, now that you have the algorithm, you only have to process the output of cat.

    An example:

    #define _POSIX_C_SOURCE 200809L
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    
    int main(void)
    {
        char *str = NULL;
        size_t size = 0;
        ssize_t len = 0;
        int line = 1;
    
        while ((len = getline(&str, &size, stdin)) != -1)
        {
            printf("%2d) length = %2zd | %s", line++, len, str);
        }
        free(str);
        return 0;
    }
    

    gcc -o demo demo.c
    cat demo.c | ./demo
    

    Output:

     1) length = 32 | #define _POSIX_C_SOURCE 200809L
     2) length =  1 | 
     3) length = 19 | #include <stdio.h>
     4) length = 20 | #include <stdlib.h>
     5) length = 23 | #include <sys/types.h>
     6) length =  1 | 
     7) length = 15 | int main(void)
     8) length =  2 | {
     9) length = 22 |     char *str = NULL;
    10) length = 21 |     size_t size = 0;
    11) length = 21 |     ssize_t len = 0;
    12) length = 18 |     int line = 1;
    13) length =  1 | 
    14) length = 54 |     while ((len = getline(&str, &size, stdin)) != -1)
    15) length =  6 |     {
    16) length = 61 |         printf("%2d) length = %2zd | %s", line++, len, str);
    17) length =  6 |     }
    18) length = 15 |     free(str);
    19) length = 14 |     return 0;
    20) length =  2 | }
    21) length =  1 |