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 prev
se 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