我正在开发一个自定义shell。在这个任务中,我需要实现唯一性命令。给定已排序的行,uniq应该能够打印所有唯一值和(如果命令为uniq -c)它们的出现次数。(. 示例代码在最后说明。
我对这个算法没有问题。我写了一个函数,它的运算和我们期望的完全一样。然而,问题是,这些输出和输入类型是什么?我的意思是,当我命令cat input。txt时,这些行是一个字符串还是一个数组?正如我所说,算法是可以的,但我不知道如何在shell中应用正确的算法?任何帮助或想法都是感激的。
$cat input.txt
Cinnamon
Egg
Egg
Flour
Flour
Flour
Milk
Milk
$cat input.txt | uniq
Cinnamon
Egg
Flour
Milk
这些行是一个字符串还是数组
这些行是fork的结果,只是发送给stdout
的字符串。
getline
在这些情况下非常有用,现在你有了算法,你只需要处理cat
的输出。
一个例子:
#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
输出:
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 |
格式为字节序列。如何储存取决于你自己。你的设计选择。
cat input.txt
打开文件input.txt
,读取字节并将其发送到"屏幕";(标准输出)。
uniq
从"键盘"(标准输入)和……做独特的事情。并将输出发送到"屏幕"。如果您愿意,您可以自己尝试一下——只运行uniq
本身,或uniq -c
——停止命令并使其处理最后一行,按enter键完成该行,然后按Ctrl-D。
当你执行cat input.txt | uniq
时,shell运行cat input.txt
,它运行uniq
,但它重定向cat
的"屏幕";到uniq
的"键盘"。就像你运行cat input.txt
然后不管它显示什么,你把它输入uniq
。
据我所知,你是在写一篇"假装"的文章。Shell,而您的Shell不会实际运行这两个命令并将它们连接起来,因此您对如何做到这一点不感兴趣,只对如何模拟它感兴趣。
需要注意的是,字节直接从cat
到uniq
。它不会首先将它们全部保存到一个流中。因此,如果第一个命令很慢,uniq
将能够在行准备好后立即处理它们,并且它不必等到第一个命令完成后才开始执行惟一的操作。使用cat
命令时,您无法分辨出差异,除非文件非常大,无法用字符串表示,但是使用其他命令时您可能会注意到这一点。
对于您的虚拟shell,按顺序一次处理一行命令可能是最简单的。
当我命令cat input.txt时,这些行只是一个字符串还是它们在数组中给出?
如果您正在执行外部cat
命令*,则输出将写入该命令的标准输出。这是I/O,而不是共享内存。一旦这些数据从cat
中出现,就不再适合根据cat
为它们使用的任何内部数据结构来描述它们。它们只是一串字符。如果另一个命令使用这些数据,那么它会选择自己的数据结构来处理它们。
以及如何您的uniq
使用这些数据?两种方式之一:
-
cat
的输出将被重定向到一个文件,uniq
随后打开并读取该文件。cat input.txt > temp; uniq temp
或
-
cat
的输出将被重定向到uniq
的标准输入。cat input.txt | uniq
UNIX的组织原则之一是,每个I/O端点在逻辑上都是一个文件,因此可以或多或少地以相同的方式处理。在情况(1)中,您将open()
或fopen()
命名文件,而在情况(2)中,您将使用预连接的文件描述符0或stdin
流,但是一旦您决定使用哪一个,两者都是一样的。
*如果你正在执行自己的内部cat
,那么你比我们更了解细节。