awk: combina expressões por OR lógico

awk: combina expressões por OR lógico

Quero combinar (OR lógico) duas expressões awk. Separadamente ambos funcionam bem. A primeira expressão imprime a linha logo antes do termo de pesquisa. A segunda expressão apenas imprime a linha que contém um caractere especial. Se eu combinar a expressão Bothe com um operador OR, recebo o erro '

^ nova linha inesperada ou fim de string

'

awk '(({$0~/\*/; print a; a=$0}) || (/\→/))' file.txt

arquivo.txt fica assim:

foo
*
bla
bla
bar→
bar→
foo
*
bla
bla
bar→
foo
*
bla
bar→
bar→

Resultado esperado:

foo
bar→
bar→
foo
bar→
foo
bar→
bar→

Responder1

Lendo seus requisitos, você descrevedoisexpressões diferentes paradois trabalhos diferentes. Você diz :

First expression prints the line right before the search term
Second expression just prints the line that contains a special character

O que significa que essas duas expressões NÃO podem ser combinadas em OR. Você combina com expressões OR que executarão a mesma ação.

Como resultado, a resposta correta de acordo com o seu texto é:

$ awk '/\*/{print a}{a=$0}/\→/' <<<"$a"
foo
bar→
bar→
foo
bar→
foo
bar→
bar→

Se você realmente precisa usar uma condição OR para executar a mesma ação para duas condições diferentes, você também pode fazer assim:

awk '/[*→]/{print a; a=$0}' file

Responder2

Com a nota sobre a impressão doanteriorlinha ao ver um asterisco, e oatuallinha ao ver um :

awk '/\*/ {print prev} /\→/ {print} {prev=$0}' file.txt

/pattern/ {action}é a abreviação de $0 ~ /pattern/ {action}. A primeira ação imprime a variável prevse houver um asterisco na linha, a segunda imprime a linha atual se houver uma seta e, por fim, imprimimosincondicionalmentesalve a linha atual em prev, para que fique disponível para impressão se a próxima linha corresponder.

Responder3

Isso deve funcionar:

awk '/\*/ || /→/ {print}' /path/to/file

Responder4

Isso fornece os resultados esperados que você cita. Não há necessidade de escapar do * porque podemos confiar no "No POSIX awk e gawk, o '*', '+' e '?' operadores representam-se quando não há nada na regexp que os preceda." comportamento aqui, mais detalhes emhttps://www.gnu.org/software/gawk/manual/gawk.html#Regexp

$ awk '/*/||/→/' file.txt
foo*
bar→
bar→
foo**
bar→
foo*
bar→
bar→
$

Usando grep em vez disso:

$ grep -E '\*|→' file.txt

informação relacionada