从模式空间中删除第一行的便携式方法(当存在多行时)

从模式空间中删除第一行的便携式方法(当存在多行时)

从模式空间中删除第一行1 的
便携式方法是什么? 与gnu sed我能做的

s/[^\n]*\n//

但据我所知,这(\n在括号[]表达式中使用)是不可移植的。


实际例子:此处,sed打印文件的最后一部分,包括分隔符通过可移植代码。我想从模式空间中删除第一行,以便排除分隔符并以可移植的方式执行此操作。很gnu sed简单:

sed 'H;/===/h;$!d;//d;x;s/[^\n]*\n//' infile

1:显然这应该在不重新启动命令周期的情况下完成......

答案1

可移植地完成此类事情的一种方法如下:

sed -e '
   # ... assuming prev sed cmds made pattern space carry newline(s)
   y/\n_/_\n/     ;# exchange newlines with an underscore
   s/^[^_]*_//    ;# remove up till the first underscore, ummm newline
   y/\n_/_\n/     ;# revert the transformation
' 

答案2

我没有合适的 sed 来尝试,但您始终可以进行内部循环测试和删除字符,直到到达换行符:

sed 'H
/===/h
$!d
//d
x
{
   :rpt
   s/^\n//
   t done
   s/.//
   t rpt
}
:done
'

第二个测试分支t rpt需要是 at而不是 a,b以便重置表示s自上次读取以来 an 已成功的内部标志。您不需要{},它们只是为了更好地显示循环。

答案3

愚蠢,但工作:

sed 'h;G;s/\n/&&/;s/^\(.*\)\n\(.*\)\n\1\2$/\2/'

那是什么?将整个内容加倍,然后用两个换行符替换第一个换行符。所以你有两次相同的内容,在第一行之后有一个额外的换行符。通过反向引用,您现在可以识别不同的部分。

如果您不想使用保持缓冲区:

sed 's/.*/&&/;s/\n/&&/;s/^\(.*\)\n\(.*\)\1\2$/\2/'

不,我不喜欢那样。如果有办法避免它,就避免它。

相关内容