столбцов с awk

если iptables запущен на вашей машине, вам нужно открыть его для этих двух портов, которые вы упомянули.

чтобы проверить, работает ли iptables, выполните команду:

service iptables status

если работает, отредактируйте файл /etc/sysconfig/iptables и введите эти две строки:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 6667 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 6697 -j ACCEPT

затем выполните

service iptables restart

если iptables не работает, дело может быть в другом, например, ваш провайдер VPS не разрешает прохождение IRC-трафика. Прочитайте условия предоставления услуг и посмотрите, нет ли там чего-нибудь, что говорит вам что-то вроде "вы не можете запускать irc-серверы" или что-то подобное.

1
27.08.2015, 02:24
5 ответов

Пожалуйста, не используйте awk sed и т.д. Они не могут правильно обрабатывать XML. XML делает кучу вещей, таких как наличие пробелов, переносов строк, унарных тегов и т.д., что означает, что регулярные выражения не очень надежны - они беспорядочно ломаются после совершенно корректного изменения XML.

Способ обработки XML - это парсер. xmlstarlet широко используется в Linux. Поскольку я еще не видел, чтобы это предлагалось - я бы использовал perl. Например:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> parsefile ('your_xml_file.xml'); 
foreach my $HW ( $twig -> findnodes ( '//HARDWARE' ) ) {
    print join ( "\t", map { $_ -> text } $HW -> children ),"\n";
}
  • Разбор XML
  • итерация элементов HARDWARE.
  • извлекаем текст из дочерних элементов
  • печатаем его.

Вы можете немного расширить его, чтобы позволить вам обрабатывать, например, различные наборы/порядок полей:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my @fields_to_show = qw ( OS NAME ); 

my $twig = XML::Twig -> parsefile ( 'your_filename.xml' ); 
foreach my $HW ( $twig -> findnodes ( '//HARDWARE' ) ) {
    my %fields =  map { $_ -> tag => $_ -> text } $HW -> children;
    print join ("\t", @fields{@fields_to_show}),"\n"; 
}

Он генерирует хэш (ассоциативный массив) под названием %fields, который выглядит так (для каждого элемента):

$VAR1 = {
          'OS' => 'Windows 7',
          'NAME' => 'WIN1',
          'DOMAIN' => 'contoso.com',
          'IP' => '1.2.3.4'
        };

А затем мы используем @fields_to_show, чтобы указать, какие поля отображать и в каком порядке.

Таким образом, будет выведено:

Windows 7   WIN1
Windows 8   WIN2

NB: Я также должен "исправить" ваш XML, потому что без одного корневого тега он недействителен. Об этом упоминалось в других ответах. Спецификация XML довольно строга - сломанный XML должен быть отвергнут. Поэтому на самом деле "исправлять" XML - это очень плохая форма, и обычно я бы предложил ударить того, кто его создал, по голове копией спецификации XML.

0
29.04.2021, 00:24

С небольшими изменениями в XML заключите весь XML в родительский тег 1 или другой из по вашему выбору, файл с именем data.xml :

<DATA>
<HARDWARE>
    <NAME>WIN1</NAME>
    <OS>Windows 7</OS>
    <IP>1.2.3.4</IP>
    <DOMAIN>contoso.com</DOMAIN>
</HARDWARE>
<HARDWARE>
    <NAME>WIN2</NAME>
    <OS>Windows 8</OS>
    <IP>10.20.30.40</IP>
    <DOMAIN>contoso.com</DOMAIN>
</HARDWARE>
</DATA>

Использование xmlstarlet + столбец

 xmlstarlet sel -T -t -m /DATA/HARDWARE -v "concat(NAME,' ',OS,' ',IP,' ',DOMAIN)" -n data.xml | column -t 

дает:

WIN1  Windows  7  1.2.3.4      contoso.com
WIN2  Windows  8  10.20.30.40  contoso.com

Редактировать:

На основе замечательных материалов Peter.O. поймайте в комментариях и его ответ ниже , давайте отправим вывод с разделителями 2 в столбец -ts $ '|' , что-то вроде:

xmlstarlet sel --indent-tab -T -t -m /DATA/HARDWARE -v "concat(NAME,'|',OS,'|',IP,'|',DOMAIN)" -n data.xml | column -ts$'|'

Теперь , поля хорошо выстраиваются, даже если в них есть пробелы:

WIN1              Windows 7  1.2.3.4 release 5  contoso.com
Really long OS X  Windows 8  10.20.30.40        contoso.com

1. Или используйте {echo ''; cat имя_файла; эхо ''; } | xmlstarlet ... , как отмечает Peter.O в комментарии ниже

2. Использование пробела в качестве разделителя не приводит к правильному выравниванию столбцов

6
29.04.2021, 00:24

С вашим примером и GNU sed:

sed -n 's/<[^>]*>//g;s/^ *//g;/./p' file | paste -d ";" - - - - | column -t -s ";"

Выход:

WIN1  Windows 7  1.2.3.4      contoso.com
WIN2  Windows 8  10.20.30.40  contoso.com

Я предполагаю, что ваш файл не содержит ;. Если вам нужен CSV, удалите | column -t -s ";".

2
29.04.2021, 00:24

with awk - произвольно задайте каждому столбцу длину 15 символов, выравнивание по левому краю и заполнение пробелами:

awk ' BEGIN { FS = "<[A-Za-z/]+>" } { if ( NR % 6 == 0 ) { printf"\n" } else if ( $2 != "" ) { printf"%-15s", $2 } }' file

Или как в других ответах в комбинации с column

awk ' BEGIN { FS = "<[A-Za-z/]+>" } { if ( NR % 6 == 0 ) { printf"\n" } else if ( $2 != "" ) { printf"%s ", $2 } }' file | column -t
0
29.04.2021, 00:24

Следующий awk скрипт (плюс column для табуляции вывода) обработает любую последовательность размещения sub-тегов, и любое разделение пробелов между тегами - т.е. он будет обрабатывать входной формат примера OP, а также следующий пример, который имеет без пробелов и по-разному упорядоченные подтеги:

    <HARDWARE><OS>Windows 7</OS><IP>1.2.3.4</IP><DOMAIN>contoso.com</DOMAIN><NAME>WIN1</NAME></HARDWARE><HARDWARE><NAME>WIN2</NAME><OS>Windows 8</OS><DOMAIN>contoso.com</DOMAIN><IP>10.20.30.40</IP></HARDWARE>  

awk 'BEGIN{ RS="[[:space:]]*</?HARDWARE>[[:space:]]*"
            FS="[[:space:]]*<|</[^<>/]+>[[:space:]]*"
            tn=split( "NAME OS IP DOMAIN", tag_order, " " ) 
     } 
     $0 { delete tag
          for( i=1;i<=NF;i++ ) if($i) { n=index($i,">"); tag[substr($i,1,n-1)]=substr($i,n+1)  } 
          for( i=1;i<=tn;i++ ) printf "%s\t", tag[tag_order[i]]; print ""
     }' file | column -ts$'\t'

вывод:

WIN1  Windows 7  1.2.3.4      contoso.com
WIN2  Windows 8  10.20.30.40  contoso.com
1
29.04.2021, 00:24

Теги

Похожие вопросы