Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.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
sed有没有一种简单的方法';h';如果保持空间为空且';H';如果不是空的?_Sed - Fatal编程技术网

sed有没有一种简单的方法';h';如果保持空间为空且';H';如果不是空的?

sed有没有一种简单的方法';h';如果保持空间为空且';H';如果不是空的?,sed,Sed,例如,将包含foo的行移动到其他行之前-- 这里,第一个H命令在第一个foo之前生成一个空行 现在作为一种解决方法,我用${x;s/^\n/;p;}-- 如果你想考虑 AWK < /代码>,那就很简单: printf '%s\n' bar1 foo1 foo2 bar2 | awk '!/foo/{a[++n]=$0; next} 1; END{for (i=1; i<=n; ++i) print a[i]}' 如果保持空间为空,sed是否有一种简单的方式转换为“h”,如果不为空,则转换

例如,将包含
foo
的行移动到其他行之前--

这里,第一个
H
命令在第一个
foo
之前生成一个空行

现在作为一种解决方法,我用
${x;s/^\n/;p;}
--


如果你想考虑<代码> AWK < /代码>,那就很简单:

printf '%s\n' bar1 foo1 foo2 bar2 |
awk '!/foo/{a[++n]=$0; next} 1; END{for (i=1; i<=n; ++i) print a[i]}'
如果保持空间为空,sed是否有一种简单的方式转换为“h”,如果不为空,则转换为“h”

不,你可以:

x; /^$/!{     # if hold space is not empty
   x;H;       # do H
bEND; }; {    # if hold space is empty (ie. branch to end if not empty)
   x;h;       # do h
}; :END;
在脚本中,它看起来像:

printf '%s\n' bar1 foo1 foo2 bar2 | sed -n '/foo/!{x;/^$/!{x;H;bEND};x;h;:END}; /foo/p; ${x;p}'
但是TBH有一个更简单的方法-从输出中删除换行符

${x;s/^\n//;p;}

如果您对
awk
没有问题,请尝试以下内容

printf '%s\n' bar1 foo1 foo2 bar2 | 
awk '
/^foo/{
  print
  next
}
!/^foo/{
  val=(val?val ORS:"")$0
}
END{
  print val
}'
简要说明:检查
printf
输出的所有行,这些行作为标准输入发送到
awk
。然后打印从
foo
开始的行,否则继续将其值添加到变量
val
。在
END
块的
awk
中,将在所有输入完成读取后执行,在那里打印变量
val

这可能适用于您(GNU-sed):

如果行包含
foo
打印,否则将其附加到保留空间

如果不是最后一行,请删除它,否则将其替换为保留空间,删除第一个字符并打印结果


注意:非
foo
行只有在第一个位置添加后才会打印。打印取决于通过替换命令标志
p
删除引入的换行符。如果保持空间为空,
d
命令将阻止隐式打印。因此,
H
命令提供了一种确定是否已使用保留空间的方法。

@anubhava我想将
foo
行移动到其他行的前面。(先打印包含
foo
的行,然后再打印其他行。)是的,我知道awk在这里更容易。我只是想看看塞德是否能轻松地做到这一点。:)看到n-sed的答案,我肯定觉得不容易:)有时只是为了好玩。:)根据你的,稍微短一点:
sed-n'/foo/!{x;/./{x;H;bq};x;H;:q}/foo/p${x;p}
:)如果文件包含空行或所有行都包含
foo
,该怎么办?从您那里学到了一些东西:
/
s///p
,以及较短的
s////code>。这在GNU sed和BSD(macos)sed中都适用。
printf '%s\n' bar1 foo1 foo2 bar2 | sed -n '/foo/!{x;/^$/!{x;H;bEND};x;h;:END}; /foo/p; ${x;p}'
${x;s/^\n//;p;}
printf '%s\n' bar1 foo1 foo2 bar2 | 
awk '
/^foo/{
  print
  next
}
!/^foo/{
  val=(val?val ORS:"")$0
}
END{
  print val
}'
sed '/foo/p;//!H;$!d;x;s/.//p;d' file