通过带有awk的正则表达式将单行数据分隔为多行?

通过带有awk的正则表达式将单行数据分隔为多行?,awk,sed,Awk,Sed,有一个40mb的单行文件,其中没有固定的宽度或定界字符。但每个记录都以一个P开头,后跟一个P或S,然后是一个数字。所以可能是这样的: 第5页 -或- PS5 或PP0等 最好的办法是什么 $ echo PP5xxxPS5yyyyPP0zzz | awk -F'P[PS][0-9]' -v OFS='\n' '{$1=$1}1' xxx yyyy zzz 因为第一行是以分隔符开头的,所以如果重要的话,可以删除它 如果要保留分隔符,使用sed可能更容易 $ echo PP5xxxPS5yyyyP

有一个40mb的单行文件,其中没有固定的宽度或定界字符。但每个记录都以一个P开头,后跟一个P或S,然后是一个数字。所以可能是这样的:

第5页 -或- PS5 或PP0等

最好的办法是什么

$ echo PP5xxxPS5yyyyPP0zzz | awk -F'P[PS][0-9]' -v OFS='\n' '{$1=$1}1'

xxx
yyyy
zzz
因为第一行是以分隔符开头的,所以如果重要的话,可以删除它

如果要保留分隔符,使用
sed可能更容易

$ echo PP5xxxPS5yyyyPP0zzz | sed 's/P[PS][0-9]/\n&/g'

PP5xxx
PS5yyyy
PP0zzz
借用,这可能是您想要的(使用GNU awk进行多字符RS和RT):

gawk解决方案与@karakfa建议的sed解决方案之间的差异如下:

  • sed解决方案将在输出开始处打印一个空行,而上述解决方案不会打印,并且
  • sed解决方案将一次性将整个输入行读入内存,而上述解决方案一次仅将一个RS分离的块读入内存。只有当您的输入太大而无法同时放入内存时,这才有关系
  • sed脚本可移植到任何版本的sed,该版本允许替换文本中的
    \n
    表示“换行符”,并且很容易修改为在其他版本中使用转义文字换行符,而上述内容需要GNU awk
  • 这行先是p,然后是p/S,然后是#。行的起点是行的终点,所以为什么不使用固定的RS而不是正则表达式呢。也许吧

    {mawk/mawk2/gawk} 'BEGIN { FS = "^$" ; RS = "\nP" ;
        
        } FNR==1 { sub(/^P/, "") } { print "P" $0 } ' 
    
    让我们把p取下来,把它印回去。第一行的打印+下一行或单子行()。我更喜欢FNR==1只运行一次的条件,而不是要求FNR>1的相反条件

    是的,从技术上讲,最后一行不会被RS分割。这是awk已知的弱点之一——最后一行将使用相同的ORS打印,无论EOF是否带有RS


    我这样写是为了允许没有RT的变体(基本上是其他所有人)。RT使生活变得轻松。

    有几种方法可以处理此问题,正确的方法取决于数据中的其他内容。您的问题将显示一个简洁、可测试的示例输入和预期输出,以便我们可以帮助您。看看这是否还不清楚。
    {mawk/mawk2/gawk} 'BEGIN { FS = "^$" ; RS = "\nP" ;
        
        } FNR==1 { sub(/^P/, "") } { print "P" $0 } '