将具有特定分隔符的多行连接到一行

Join multiple rows with specific delimiter to one row

我想连接多行,在这种情况下,分隔符后面总是有 4 行,但这并不意味着将来其中一行可以包含 4 行中的更多行。无论如何,我想在使用该分隔符 -- 时将它们排成一排,并将他从最终视图示例中排除:

--
        CATALOG
        DB1
        1
         good
--
        USERS
        DB2
        3
         good

我用 tr 尝试了几件事,也 awk 没有成功。

我最后想表达的观点是:

CATALOG DB1 1 good
USERS DB2 3 good

我会将记录分隔符设置为 --,然后遍历字段:

awk -v RS="--" 'NF{for (i=1;i<=NF;i++) printf ("%s%s", $i, (i==NF?"\n":FS) )}' file

说明

  • -v RS="--" 将记录分隔符设置为 -- 而不是默认的新行
  • NF{}只要记录中有字段,就按括号里面的做。
  • for (i=1;i<=NF;i++) printf ("%s%s", $i, (i==NF?"\n":FS) ) 遍历打印所有字段的字段。它们之间的分隔符始终是 FS(其默认值为 space),如果我们正在处理最后一个,则换行。

测试

有额外的行。

$ cat a
--
        CATALOG
        DB1
        1
         good
--
        USERS
        DB2
        3
         good
    bad
$ awk -v RS="--" 'NF{for (i=1;i<=NF;i++) printf ("%s%s", $i, (i==NF?"\n":FS) )}' a
CATALOG DB1 1 good
USERS DB2 3 good bad
sed '#n
/^--$/ b print
H;$!b
:print
s/.*//;x;s/^[[:cntrl:][:space:]]*//;s/[[:cntrl:][:space:]]\{1,\}/ /gp' YourFile
  • 删除以 -- 开头的行,如果出现则打印缓冲区内容(最后一节)
  • 加载缓冲区当前行
  • 如果不是文件循环结束
  • 通过删除 space 和换行
  • 重新格式化后打印内容(因此结束或新部分)

这里是一个简单的gnu awk(gnu 由于 RS 中有多个字符)。

awk -v RS="--" '{=}NR>1' file
CATALOG DB1 1 good
USERS DB2 3 good

= 这将使用新的记录选择器重新创建文件,并使用默认字段 space.
NR>1 然后打印除第一行(空白)以外的所有行。