【问题标题】:Read line by line between a pattern, then print in de-limited format在模式之间逐行读取,然后以分隔格式打印
【发布时间】:2014-05-27 06:59:27
【问题描述】:

我有一个 ascii 文件,内容如下:

START
this is my home
this is my pc

START
this is my linux
this is my awk
this is nice

START
this is a single line

START
this is my work
this is the end
this line has to be read

START
...
...

START
.
.
.
.

我想读取 START 和空白行之间的行并以分隔格式打印输出。 输出应为以下格式:

this is my home;this is my pc
this is my linux;this is my awk;this is nice
this is a single line
this is my work;this is the end;this line has to be read

我使用分号作为分隔符。 请注意:START 和 Blank 行之间的行数不固定。

我尝试过使用 awk,但在 START 之后我只能读取一行

awk 'BEGIN { RS = "START" } ; { print $1 }'

谁能引导我到正确的论坛/正确的方向...

谢谢

【问题讨论】:

    标签: linux awk


    【解决方案1】:

    你可以这样做:

    awk -v RS="" '{$1=$1}1' file
    START this is my home this is my pc
    START this is my linux this is my awk this is nice
    START this is a single line
    START this is my work this is the end this line has to be read
    

    确保每个部分都包含 START 并将其删除:

    awk -v RS="" '{$1=$1} /^START/ {gsub(/^START /,"");print}' file
    this is my home this is my pc
    this is my linux this is my awk this is nice
    this is a single line
    this is my work this is the end this line has to be read
    

    为您提供一些有关您的 awk 失败原因的更多信息。
    您需要在更改 RS 后重建每一行,使用 $1=$1
    然后通过1{print $0}打印整行
    所以让你的awk工作:

    awk 'BEGIN { RS = "START" } {$1=$1} 1' file
    

    或者像这样

    awk -v RS="START" '{$1=$1} NR>1' file
    

    NR>1 防止第一个空行表单成为打印机。

    RS 中的多个字符,使其不那么便携,你需要gnu awk

    【讨论】:

      【解决方案2】:
      $ awk -v RS= '{$1=$1} sub(/^START /,"")' file
      this is my home this is my pc
      this is my linux this is my awk this is nice
      this is a single line
      this is my work this is the end this line has to be read
      

      【讨论】:

        【解决方案3】:

        这将构建一个包含输入文件相关部分的单个字符串,其中块由“\n”分隔,行由“;”分隔。

        awk '
          t && $0 == "" { t = 0 ; sep = "\n" }
          t             { hold = hold sep $0 ; sep = ";" }
          $0 == "START" { t = 1 }
          END           { print hold }
        ' file
        

        第一行处理块的结束。

        如果设置了块内触发器,则第二行附加一个分隔符(“”、“\n”或“;”,视情况而定)和当前记录到保持缓冲区。

        第三行设置块启动时的触发器——如果块已经启动,“START”行将被视为块的一部分。

        【讨论】:

          【解决方案4】:

          接受的答案不会将每个行块中的各个行保留为单独的字段,在输出中用; 分隔;以下是:

          awk -v RS='' -F'\n' -v OFS=';' '{sub(/^START\n/,""); $1=$1; print }' file
          
          • RS=''(将输入记录分隔符 RS 设置为空字符串)是具有特殊含义的 awk idiom:它将输入分解为基于行的 blocks在空行上作为分隔符;换句话说:每个连续的非空行块形成一个记录。
          • -F'\n'input 字段分隔符(也可作为特殊变量 FS 访问)设置为换行符,因此每条记录(行块)中的 每一行 将变为它自己的字段
          • 根据 OP 的要求,OFS=';'output 字段分隔符设置为 ;
          • sub(/^START\n/,"") 从每条记录(行块)中删除 START 行(加上它的尾随换行符)。
          • $1=$1 是一个技巧,通过分配给字段变量,使用 OFS 的值作为分隔符,从其各个字段中重建输入记录;在这里,各个行(没有尾随的换行符) - 与; 有效地连接在一起形成一个行。
          • print 只是输出重建的记录。

          【讨论】:

            猜你喜欢
            • 2013-12-08
            • 1970-01-01
            • 1970-01-01
            • 2016-01-04
            • 2012-03-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-03
            相关资源
            最近更新 更多