Combine múltiplas expressões regulares de um único arquivo usando o awk

4

Estou tentando analisar um arquivo HTML usando scripts de shell.

Existem 4 expressões regulares diferentes que preciso capturar: name= , age= , class= , marks= .

Usando

grep "name=\|age=\|class=\|marks=" student.txt

Consigo obter as linhas necessárias, mas, juntamente com essas linhas correspondentes, também preciso imprimir a segunda linha de cada partida que contenha a pontuação.

Referindo-se à pergunta: Print Matching linha e enésima linha da linha correspondente .

Eu modifiquei o código para:

awk '/name=\|age=\|class=\|marks=/{nr[NR]; nr[NR+2]}; NR in nr' student.txt

Mas isso não parece funcionar. Como pesquiso várias expressões regulares no mesmo comando awk ?

    
por debal 29.08.2013 / 17:18

4 respostas

7

Experimente:

awk '/foo/||/bar/' Input.txt
    
por 29.08.2013 / 17:39
4

% regexpsawk são regexps estendidos, enquanto grep sem -E são regexp básico. Com regexp estendido:

awk '/name=|age=|class=|marks=/{nr[NR]; nr[NR+2]}; NR in nr'

Observe que o regexp básico padrão não tem um operador de alternância, então

grep 'a\|b'

Normalmente não funciona em todos os grep (enquanto alguns como o GNU grep o suportam como uma extensão).

grep -E 'a|b'
grep -e a -e b
grep 'a
b'

Funcionará em todos os grep .

    
por 29.08.2013 / 22:22
1

Já tentou utilizar o sinalizador "-A" com o grep? Ele irá imprimir linhas de contexto à direita após a partida. Por exemplo: grep -A1 foo file.txt corresponderá e imprimirá as linhas com a palavra foo e também imprimirá a linha imediatamente a seguir.

    
por 29.08.2013 / 17:42
1

Usando o grep

E se você usou a opção after context para grep ( -A ) e especificou um 1 para obter a primeira linha após uma correspondência?

$ grep -E -A 1 "name=|age=|class=|marks=" student.txt

Exemplo

Arquivo de amostra.

$ cat student.txt 
name=
1st line after name
2nd line after name
age=
1st line after age
2nd line after age
class=
1st line after class
2nd line after class
marks=
1st line after marks
2nd line after marks

Então, quando você executar o comando acima:

$ grep -E -A 1 "name=|age=|class=|marks=" student.txt
name=
1st line after name
--
age=
1st line after age
--
class=
1st line after class
--
marks=
1st line after marks

Usando o awk

Como @RahulPatil sugeriu usar a construção para awk :

'/string1/||/string2/||...'

Algo como isso faria o que você está procurando.

$ awk '
  /name=/||/age=/||/class=/||/marks=/{nr[NR]; nr[NR+1]}; NR in nr
' student.txt 

Exemplo

$ awk '
  /name=/||/age=/||/class=/||/marks=/{nr[NR]; nr[NR+1]}; NR in nr
' student.txt
name=
1st line after name
age=
1st line after age
class=
1st line after class
marks=
1st line after marks
    
por 29.08.2013 / 17:40