Bash 使用Awk将漂亮的打印表格转换为带有分隔符的单行

Bash 使用Awk将漂亮的打印表格转换为带有分隔符的单行,bash,awk,text-parsing,separator,Bash,Awk,Text Parsing,Separator,正在尝试清理Python客户端的输出。这是一个例子: +--------------------------+-----------+ | Text | Test | +--------------------------+-----------+ | 111-222-333-444-55555555 | 123456789 | | 111-222-333-444-55555555 | 123456789 | | 111-222-333-444-

正在尝试清理Python客户端的输出。这是一个例子:

+--------------------------+-----------+
| Text                     | Test      |
+--------------------------+-----------+
| 111-222-333-444-55555555 | 123456789 |
| 111-222-333-444-55555555 | 123456789 |
| 111-222-333-444-55555555 | 123456789 |
+--------------------------+-----------+
我首先通过管道输出移除顶部和底部:

Command_Output | tail -n +4 | head -n -1 |
现在我们有以下几点:

| 111-222-333-444-55555555 | 123456789 |
| 111-222-333-444-55555555 | 123456789 |
| 111-222-333-444-55555555 | 123456789 |
111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789
现在,我试图删除表中的管道,并将表转换为一行逗号分隔的行。不过,保持两个数字之间的相关性很重要,所以也许我应该使用两个分隔符。也许最终输出应该如下所示:

| 111-222-333-444-55555555 | 123456789 |
| 111-222-333-444-55555555 | 123456789 |
| 111-222-333-444-55555555 | 123456789 |
111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789
所以现在我在这一点上:

Command_Output | tail -n +4 | head -n -1 | awk '{$3 = "~"; print $0;}'
有人能帮我做最后一部分吗?我需要将表放入一行逗号分隔的行中。

有效,但:

  • 仅限于一组输入线,所有输入线都作为单个输出线输出

    • 如果不需要分组逻辑,请考虑.
  • 使用几个特定于GNU的选项,这些选项通常不会在非Linux平台上工作

  • 使用4个外部进程,1个即可

一种通用解决方案,仅使用一个符合POSIX标准的
awk
命令(仍然采用两列布局),将共享相同(概念上)第一列值的每一行块输出为一行:

…|awk'
天然橡胶

感谢您的帮助

一个更简单的基于awk的解决方案:

Command | awk -vORS=, '($1=="|" && NR>3 ) {print $2"~"$4}'
但是,这会在末尾留下一个尾随的
。要解决这个问题:

Command | awk -vORS= '($1=="|" && NR>3 ) {if (NR>4) {print ","}; print $2"~"$4}'
其中:

111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789

这将适用于任意数量输入列的所有AWK:

$ awk -F ' *[|] *' -v OFS='~' 'NF>1 && ++c>1 {$1=$1; gsub(/^~|~$/,""); printf "%s%s", (c>2?",":""), $0} END{print ""}' file
111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789

整个工作可以在单个
awk
命令中完成;也不需要
尾部
头部
sed
。非常简单,但是(a)通常不建议仅根据标题行和数据行的内容来区分它们(可能没有可靠的区别)和(b)您的解决方案添加了一个尾部
而不是输出的换行符。改为使用NR修复了上面的问题。更好,但是现在您缺少了一个尾随的
\n
(实用程序通常期望在文件末尾)。在
-v
之后没有空格会导致不必要的特定于gawk。在使用awk时,您不需要其他工具和管道。此外,这仅限于2个输入列,并且依赖于不可移植的sed bahavior(
\n
表示换行符)和GNU awk(在
-v
之后没有空格)以及未定义的POSIX行为(期望sed能够在不终止换行符的情况下处理输入)。
$ awk -F ' *[|] *' -v OFS='~' 'NF>1 && ++c>1 {$1=$1; gsub(/^~|~$/,""); printf "%s%s", (c>2?",":""), $0} END{print ""}' file
111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789,111-222-333-444-55555555~123456789