Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用grep/sort删除行中的多个换行符_C_Shell_Sorting_Filter_Grep - Fatal编程技术网

C 使用grep/sort删除行中的多个换行符

C 使用grep/sort删除行中的多个换行符,c,shell,sorting,filter,grep,C,Shell,Sorting,Filter,Grep,我制作了一个C程序,它实现了printenv | grep[arguments]| sort | less,但出于某种原因,我在输出的开始处得到了一大堆换行符。可能是因为我是如何将环境变量从父进程写到grep进程的。如果运行我的程序路径,我的结果: /*40 blank lines */ INFOPATH=/usr/share/info MANPATH=/usr/local/vol/matlab/7.4.0/man:/usr/kerberos/man:/usr/local/share/man:/

我制作了一个C程序,它实现了printenv | grep[arguments]| sort | less,但出于某种原因,我在输出的开始处得到了一大堆换行符。可能是因为我是如何将环境变量从父进程写到grep进程的。如果运行我的程序路径,我的结果:

/*40 blank lines */
INFOPATH=/usr/share/info
MANPATH=/usr/local/vol/matlab/7.4.0/man:/usr/kerberos/man:/usr/local/share/man:/usr    /share/man/en:/usr/share/man:/usr/man
MODULEPATH=/usr/local/vol/modulefiles:/pkg/modules/modulefiles:/etc/site/modulefiles:    /usr/share/Modules/modulefiles:/etc/modulefiles
PATH=/usr/lib/heimdal/bin:/usr/local/vol/comsol/3.4/bin:/usr/local/vol/maple/10.05/bin:/usr/local/vol/matlab/7.4.0/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/opt/real/RealPlayer
WMMENUPATH=/usr/local/vol/maple/menudef/10.05:/usr/local/vol/fvwm2/menudefs/emacs:/usr/local/vol/fvwm2/menudefs/acroread
我正在使用C调用shell程序并将其与管道连接起来。每个程序(grep、sort、less/more)在它自己的子进程中被调用,并通过管道传输到其他程序。父进程通过如下管道将环境变量写入grep:

for(i=0; envp[i]!=NULL; i++)
{
    return_value = write(pipe_fd[0][PIPE_WRITE],envp[i], strlen(envp[i]));
    errorCheck(return_value, "Cannot write to pipe in parent\n");
    return_value=write(pipe_fd[0][PIPE_WRITE],"\n",1);
    errorCheck(return_value, "Cannot write to pipe in parent\n");
}

我尝试过在排序调用中添加一些选项,但到目前为止没有任何效果我的问题是如果有一种方法可以用grep或sort忽略一行中的多个换行符?

在读取最后一块输出的循环中,执行以下操作

int flag=1;
char prev='\n';
while(fgets(buf, f, sizeof(buf)) {
 if (buf[0]='\n' && prev='\n' && flag) next
 flag = 0;

如果第一行是单个\n,则将跳过此操作,并跳过任意数量的\n行,以从输出流中筛选出空行:

... | grep . | ...
或者,要过滤掉仅由空格组成的任何行:

... | grep '\S' | ...

使用grep,您可以使用

grep -v '^$'
使用awk,您可以做更多有趣的事情,比如用一行替换多行空行:

awk '/^$/ {if (!e) {e=1;print}} /./ {e=0; print}'
这将产生以下结果:

% (echo hello;echo;echo;echo;echo;echo world) | awk '/^$/ {if (!e) {e=1;print}} /./ {e=0; print}'
hello

world

注意输出中的一个空行。

你能发布你的C程序吗,否则很难找出问题所在。@snyder这个程序很大,我只想知道是否有办法用grep或sort忽略一行中的多个换行符?你的问题不清楚。您是使用C语言调用shell程序还是在自己的C程序中重新实现shell程序?您是在调用一个或两个大型管道shell命令,还是在C中实现自己的管道?要删除空行,您可以使用sed regex,例如sed'/^\s*$/d'@hyde Yes,是的,它首先打印一组新行,然后打印所有的env。变量在后面。没有循环,只有较少的进程从管道读取并写入输出。所以在“读取”和“写入”之间执行类似的操作