Bash

如何從包含製表符和空格的文本創建統一列?

  • October 8, 2015

以最簡單的形式,假設我有一個名為file.txt. 的內容file.txt如下所示:

Source                    Destination                Maximum To  Maximum From Average Total   Average To           Average From
(192.168.1.1)   (192.168.1.2)       202.89 Kbps    0 bps         645 bps 645 bps 0 bps

我嘗試了該column命令的多種變體,但均無濟於事。我怎樣才能使這個輸出看起來像這樣:

Source         Destination     Maximum To     Maximum From     Average Total     Average To     Average From
(192.168.1.1)  (192.168.1.2)   202.89 Kbps    0 bps            645 bps           645 bps        0 bps

我覺得我應該知道如何做到這一點,但我目前正在畫一個空白,到目前為止還沒有發現任何按預期工作的東西。

**編輯:**下面的評論和答案sed非常適合我的原始範例(我實際上更喜歡評論中的解決方案,因為它更簡單並且不涉及管道tr)。話雖如此,這兩種解決方案在多行文件上的性能完全相同。實際file.txt將包括數百行不同長度的 IPv4 地址。sed到目前為止,兩種解決方案都在原始(更準確)上返回了以下結果file.txt

原始文件.txt:

Source                    Destination                Maximum To  Maximum From Average Total   Average To           Average From
(10.10.10.21)     (192.168.123.122)      18.90 Kbps     0 bps         131 bps 131 bps 0 bps
(10.10.10.22)     (192.168.123.122)       10.88 Kbps     0 bps         23 bps 23 bps 0 bps
(10.10.10.23)     (192.168.123.123)       10.88 Kbps     0 bps         23 bps 23 bps 0 bps
(192.168.123.123) (192.52.168.123)       0 bps          22.84 Kbps    1.17 Kbps 0 bps     1.17 Kbps
(192.168.123.124)  (192.52.168.123)       0 bps          10.87 Kbps    19 bps 0 bps  19 bps

更新了 file.txt(到目前為止使用了兩種建議的解決方案之後):

Source                              Destination        Maximum To  Maximum From  Average Total  Average To  Average From
(10.10.10.21)                       (192.168.123.122)  18.90 Kbps  0 bps         131 bps        131 bps     0 bps
(10.10.10.22)                       (192.168.123.122)  10.88 Kbps  0 bps         23 bps         23 bps      0 bps
(10.10.10.23)                       (192.168.123.123)  10.88 Kbps  0 bps         23 bps         23 bps      0 bps
(192.168.123.123) (192.52.168.123)  0 bps              22.84 Kbps  1.17 Kbps     0 bps          1.17 Kbps
(192.168.123.124)                   (192.52.168.123)   0 bps       10.87 Kbps    19 bps         0 bps       19 bps

是否有更新的解決方案可以解釋這個抵消警告?

腳本基於 OP 的範例數據。

sed '
   s/\s\s\+/:/g
   s/\([a-z)]\)\s\([(0-9A]\)/\1:\2/g
   ' file.txt | 
column -s: -t
  • 首先更改容易找到的分隔符(2 步或更多\s步):

  • 第二個找到剩餘的可能分隔符:

    • 小寫字母和數字之間
    • )
    • A
  • 使用列分隔符格式化字元串:

下面的 perl 腳本將輸入轉換為製表符分隔的欄位,這依賴於前兩個欄位每個只有一個“單詞”而其餘欄位每個都有兩個“單詞”的知識。然後將其輸出通過管道傳輸到column -s $'\t' -t

這是一種非常笨拙和蠻力的方法,但它確實有效。

#! /usr/bin/perl 

use strict;

while(<>) {
   my (@F, @fields, $i);

   @F=split;
   $fields[0] = $F[0] ;
   $fields[1] = $F[1] ;
   for $i (0..4) {
     $fields[$i + 2] = $F[$i*2 + 2] . ' ' . $F[$i*2 + 3];
   }

   print join("\t",@fields),"\n";
}

它是這樣使用的:

$ ./bandwidth.pl bandwidth.txt | column -s $'\t' -t 
Source             Destination        Maximum To  Maximum From  Average Total  Average To  Average From
(10.10.10.21)      (192.168.123.122)  18.90 Kbps  0 bps         131 bps        131 bps     0 bps
(10.10.10.22)      (192.168.123.122)  10.88 Kbps  0 bps         23 bps         23 bps      0 bps
(10.10.10.23)      (192.168.123.123)  10.88 Kbps  0 bps         23 bps         23 bps      0 bps
(192.168.123.123)  (192.52.168.123)   0 bps       22.84 Kbps    1.17 Kbps      0 bps       1.17 Kbps
(192.168.123.124)  (192.52.168.123)   0 bps       10.87 Kbps    19 bps         0 bps       19 bps

順便說一句,這是一個很好的例子,說明為什麼使用也在被定界的欄位中的定界符(例如空格)從來都不是一個好主意。它只會讓事情變得比他們需要的更困難……並且沒有可靠的方法來區分分隔符和不需要提前了解文件內容和結構的欄位內容。

引用自:https://unix.stackexchange.com/questions/234345