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