Ler linhas especificadas no arquivo - BASH

1

Eu gostaria de ler as linhas especificadas no arquivo iptables . Quero ler as linhas iniciadas com : e terminar com espaço .

Arquivo iptables

 # Generated by iptables 04:13:50 2015
 *filter
 :INPUT ACCEPT [0:0]
 :FORWARD ACCEPT [0:0]
 :OUTPUT ACCEPT [0:0]


-A INPUT -p tcp -m tcp --sport http --dport 1024: -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --sport https --dport 1024: -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --sport webcache --dport 1024: -m state --state ESTABLISHED -j ACCEPT
COMIT
# Completed on Mon Dec 04:13:50 2015

Minha saída deve ser assim.

INPUT
FORWARD
OUTPUT

Como posso fazer isso? Eu estava pensando em sed e IFS , mas não tenho ideia de como.

Eu tenho saída como esta

13:50  
INPUT
0]
FORWARD
0]
OUTPUT
0]
13:50

depois de executado:

grep -Po ':\K[^ ]*' file

Eu quero omitir 13:50 e 0] e outras coisas relacionadas.

Meu objetivo é ter uma saída onde estejam apenas nomes de cadeias .

    
por Michal N. 28.12.2015 / 19:01

3 respostas

3

Outro sed :

sed -ne's/^:\([[:upper:]]*\).* $//p' <in >out

Este comando tenta fazer uma s/// ubstitution por linha de entrada. A menos que seja bem-sucedida, -n othing é p rinted para saída. Portanto, o /regexp/ deve corresponder a uma linha e a s/// ubstitution deve ocorrer antes de sed %% dop rint, porque seu único comando p rint é um sinalizador na declaração s/// ubstitution.

Para corresponder a uma linha de entrada, primeiro é preciso coincidir com : dois pontos na ^ cabeça da linha, seguido imediatamente por * zero ou mais caracteres alfabéticos de[[:upper:]], seguido de * zero ou mais de qualquer outro tipo de caractere . , que deve ser seguido por pelo menos um espaço na linha $ da linha.

Quando ele corresponder à sequência de [[:upper:]] -chars que são referenciados no \( sub group \) é usado para substituir a linha inteira como salva em .

Mas isso não funciona para sua entrada de exemplo porque seu exemplo começa com um espaço e termina sem um. Um regexp que funcionará para o seu exemplo:

sed -ne's/^ *:\([[:upper:]]*\).*//p'

O que é basicamente o mesmo, mas em vez de procurar um espaço definido na cauda da linha, ele procura por qualquer número de espaços na cabeça.

INPUT
FORWARD
OUTPUT
    
por 28.12.2015 / 19:35
4

Sugiro usar grep :

grep -Po '^ *:\K[^ ]*' file

Explicação:

  • -P : use expressões regulares compatíveis com perl
  • -o : imprime apenas as partes correspondentes
  • \K : recortou tudo até agora
  • [^ ]* : corresponde a tudo menos ao espaço zero ou mais vezes

Saída:

INPUT
FORWARD
OUTPUT
    
por 28.12.2015 / 19:12
3

Para fazer isso com sed :

sed -n '             # -n do not print lines to output by default
    /^:.* $/ {       # address lines beginning with colon, ending with space
        s/^://       # remove colon at beginning of line
        s/ .*//      # remove first space and everything following
        p            # print the edited line
    }
'
    
por 28.12.2015 / 19:24