Обновлено: Используя копию полного оригинала, назвав ее в этом примере full_original.txt
:
$ sed 's/\((\)/ \1/g;s/\(Average\)/ \1/g;s/ \([0-9]\)/ \1/g;s/\(\S\) \(\S\)/\1_\2/g' full_original.txt | column -t | tr _ ' '
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
Большая часть этого решения использует подход "разделяй и властвуй", когда у вас есть несколько отдельных проблем, решаемых по отдельности. Затем все это собирается в конце с помощью волшебной команды column
, с завершающим штрихом tr
:
s/searchstring/replacestring/g'
, g
- жадный/глобальный, поэтому применяется ко всем совпадениям, а не только к первому\(somegroup\)
в части поиска, может быть повторно напечатан через \1
если это первая группа, \2
если это вторая группа и т.д.;
позволяет нам поместить несколько команд поиска и замены в один экземпляр sed
, что более эффективно, чем конвейеризация и, следовательно, запуск нескольких команд типа sed command | sed command | sed command . ...
etcs/\((\)/ \1/g
имеет дело с ...123) (19...
сдвигает два значения ip, заключенные в круглые скобки, более чем на один пробел друг от друга, чтобы избежать проблемы смещения, которую обнаружил ОП. Это делается путем сопоставления любой открывающей скобки (
и префиксации пробелом, так что получается space
+(
s/\(Average\)/ \1/g
- часть, которая имеет дело с тем, что Maximum From Average Total
не имеют специального разделения, что затрудняет последующий поиск и замену, Поэтому сначала мы добавляем дополнительный пробел перед каждым вхождением Average
s/ \([0-9]\)/ \1/g
, чтобы разделить значения полей в оригинальном тексте 645 bps 645 bps 0 bps
, префиксируя любое вхождение пробел+число
пробелом, чтобы получилось пробел+пробел+число
, опять же, чтобы помочь последующей команде sed отличить их друг от другаs/\(\S\) \(\S\)/\1_\2/g
является обходным решением, она ищет не-пробел+пробел+не-пробел
и с группировкой изменяет их так, что пробел превращается в подчеркивание. Это сохраняет Maximum To
вместе для последующей column
команды, которую мы используем, так что она становится Maximum_To
| column -t
передает ее в команду column, которая, по умолчанию, man column
говорит: По умолчанию команда column объединяет несколько смежных разделителей в один разделитель при использовании опции -t
, поэтому она обрабатывает переменный пробел между текстами как один разделитель. | tr _ ' ' '
отменяет обходной путь преобразования пробелов в символы подчеркивания (_
) с помощью команды tr
, преобразует все _
обратно в пробелы ' ' '
. И таким образом вы получаете желаемый результат.