簡體   English   中英

使用Awk將漂亮打印的表格轉換為帶分隔符的單行

[英]Transform a pretty-printed table to a single line with separators, using Awk

試圖清理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

所以現在我就在這一點上:

Command_Output | tail -n +4 | head -n -1 | awk '{$3 = "~"; print $0;}'

有人可以幫助我完成最后一部分嗎? 我需要將表格放到單個逗號分隔的行中。

Atomiklan自己的答案有效,但是:

  • 被限制為輸入線,所有這些都是作為一個單一的輸出線輸出一個組。

  • 使用幾個特定於GNU的選項,這些選項通常不適用於非Linux平台。

  • 使用4個外部進程,當1表示時。

一種通用解決方案,只使用一個符合POSIX標准的awk命令(仍采用2列布局)輸出共享相同(概念上)第一列值的每個行塊作為單行:

 ... | awk '
  NR <= 3 || /^\+/ { next }                          # skip header and footer
  prev != "" && prev != $2 { printf "\n"; fsep="" }  # see if new block is starting
  { printf "%s", fsep $2 "~" $4; fsep=","; prev=$2 } # print line at hand
  END { printf "\n" }                                # print final newline
'

要處理可變數量的列

... | awk -F ' *\\| *' '
  NR <= 3 || /^\+/ { next }                          # skip header and footer
  {                                                  # process each data row
    fsep=""; first=1
    for (i=1; i<=NF; ++i) {                          # loop over all fields
      if ($i == "") continue                         # skip empty fields
      # See if a new block is starting and print the appropriate record
      # separator.      
      if (first) {  
        if (prev != "") printf (prev != $i ? "\n" : ",") 
        prev=$i                                      # save record's 1st nonempty field
        first=0                                      # done with 1st nonempty field
      }
      printf "%s", fsep $i                           # print field at hand.
      fsep="~"                                       # set separator for subsequent fields
    }
  }
  END { printf "\n" }                                # print trailing newline
'

這適用於任意數量的輸入列的所有awks:

$ 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
Command_Output | tail -n +4 | head -n -1 | awk -vORS=, '{ print $2 "~" $4 }' | sed 's/,$/\n/'

謝謝您的幫助

一個更簡單的基於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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM