【问题标题】:Removing multiple newlines in a row with grep/sort使用 grep/sort 连续删除多个换行符
【发布时间】:2013-12-01 17:12:15
【问题描述】:

我制作了一个实现printenv | 的C 程序。 grep [参数] |排序 |少,但由于某种原因,我在输出开始时收到了一堆换行符。可能是因为我如何将环境变量从父进程写入 grep 进程。如果我运行 myProgram PATH,我的结果:

/*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 忽略连续的多个换行符?

【问题讨论】:

  • 你能把你的C程序贴出来,否则很难找出问题所在。
  • @snyder 程序很大,我只想知道是否有办法用 grep 或 sort 忽略连续的多个换行符?
  • 您的问题不清楚。您是使用 C 语言调用 shell 程序还是在自己的 C 程序中重新实现 shell 程序?您是在调用一两个大型管道 shell 命令还是在 C 中实现自己的管道?
  • 要删除空白行,您可以使用 sed 正则表达式,例如 sed '/^\s*$/d' see this stackoverflow post
  • @hyde 是的,是的,它首先打印一堆换行符,然后是所有 env。变量一个接一个。

标签: c shell sorting filter grep


【解决方案1】:

在读取最终输出块的循环中,执行类似的操作

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

如果第一行是单行\n,这将被跳过,任何数量的\n行也会被跳过

【讨论】:

  • 没有循环,只有从管道读取并写入输出的较少进程。
  • 所以在“读”和“写”之间做类似上面的事情
【解决方案2】:

从输出流中过滤掉空行:

... | grep . | ...

或者,过滤掉任何只包含空格的行:

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

【讨论】:

    【解决方案3】:

    使用 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
    

    注意输出中的单个空行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      • 2013-11-06
      • 2019-01-18
      • 1970-01-01
      • 1970-01-01
      • 2014-12-01
      • 1970-01-01
      相关资源
      最近更新 更多