Parece um pouco estranho que o operador lógico de && não possa funcionar dentro do padrão awk if regex, o que versus o operador lógico de || poderia funcionar bem!
Nota: mas o operador lógico de && pode funcionar dentro do padrão awk regex puro e simples, então por quê?
#
#
# cat /etc/passwd|awk '$0 ~/[Ss]ystem/ || /puls/ {print $0}'
dbus:x:81:81:System message bus:/:/sbin/nologin
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
#
#
#
# cat /etc/passwd|awk '$0 ~/[Ss]ystem/ && /puls/ {print $0}'
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
#
#
#
# cat /etc/passwd|awk '$0 ~/[Ss]ystem|puls/ {print $0}'
dbus:x:81:81:System message bus:/:/sbin/nologin
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
#
#
#
# cat /etc/passwd|awk '{k1[NR]=$0}END{for(i=1;i<=NR;i++)if(k1[i] ~/[Ss]ystem/ || /puls/){print k1[i]}}'
dbus:x:81:81:System message bus:/:/sbin/nologin
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
#
#
# cat /etc/passwd|awk '{k1[NR]=$0}END{for(i=1;i<=NR;i++)if(k1[i] ~/[Ss]ystem/ && /puls/){print k1[i]}}'
#
#
# cat /etc/passwd|awk '{k1[NR]=$0}END{for(i=1;i<=NR;i++)if(k1[i] ~/[Ss]ystem/ && /puls/){print k1[i]}}'
#
#
# cat /etc/passwd|awk '$0 ~/[Ss]ystem/ && /puls/ {print $0}'
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
#
#
Agora, a situação mais recente pode se tornar muito mais estranha do que antes, depois que fiz algumas modificações!
Por que o mesmo padrão regex abaixo com a variável de matriz e o operador lógico && pode funcionar?
Nota: isso deve explicar que o problema de && dentro de alguns padrões if regex não tem nada a ver com a própria variável de array, pelo menos.
#
#
# cat /etc/passwd|awk '{k0[NR]=$0;if(k0[NR] ~/[Ss]ystem/ && /puls/){print k0[NR]}}'
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
#
#
# cat /etc/passwd|awk '{k0[NR]=$0;if(k0[NR] ~/[Ss]ystem/ || /puls/){print k0[NR]}}'
dbus:x:81:81:System message bus:/:/sbin/nologin
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
#
#
# cat /etc/passwd|awk '{k0[NR]=$0;if(k0[NR] ~/[Ss]ystem/ && /puls/){print k0[NR]}}'
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
#
#
na primeira parte
está implícito para
então
deve ser escrito como
/pusl/
éprovável que(*) corresponda à última linha de/etc/passwd
.man awk
mas~
(e!~
) têm prioridade sobre&&
(*) confirmado, se eu mover a linha PulseAudio para a última linha, a correspondência é feita.
Você está assumindo a associação errada de operadores e, possivelmente, seu significado. Numerando seus casos de teste:
$0 ~/[Ss]ystem/
verifica se "$0 corresponde a /RE/". A|| /puls/
condição nem sequer é testada: é "curto-circuitada" porque a condição geral já é conhecida como verdadeira.O
&&
verifica se ambas as condições são verdadeiras e corresponde a apenas uma linha.O RE combinado (dois casos alternativos com
|
) corresponde a duas linhas.Isso corresponde às duas linhas armazenadas que contêm
System
.Isso não combina com nada. Ele testa uma linha armazenada do array, mas o '/puls/' testa o valor em $0 depois que você executou o final do arquivo -- ele não se refere a k1[i]. $ 0 ainda conteria a última linha do arquivo e presumo que o arquivo de entrada completo não tenha essa linha no final. O
&&
requer que ambas as condições sejam verdadeiras, portanto, nenhuma linha corresponde.É uma duplicata de (5).
é uma duplicata de (2).
Esta é uma desconstrução de sua "situação mais recente" adicionada à sua pergunta inicial, para simplificar as coisas.
O cat não adiciona nada ao código, porque o awk pode ler os arquivos sozinho. (Google UUOC para mais.)
Armazenar a linha de entrada em uma matriz e testar o valor na mesma instrução não adiciona nada (já que não há bloco END). Então podemos simplificar para:
Usar uma
~
correspondência de padrão é idêntico a um RE simples, então simplifique para:Usar um
if
é idêntico a um padrão fora das chaves, então:print $0
é idêntico aprint
, e{ print }
como uma ação é o padrão, então:Sua afirmação inicial de que
&&
não pode funcionar e||
funciona bem é falsa.Isso é lido como "se o padrão A e o padrão B estiverem presentes nesta linha de entrada":
Isso é lido como "se o padrão A ou o padrão B estiver presente nesta linha de entrada":