Você pode usar o gsub para isso:
ip -br a | awk '/wlan0/ {gsub(/\/.*/, ""); print $3}'
Ok, aqui está um exemplo rápido; me isolando o IPV4 de um host em três etapas:
ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 DOWN
wlan0 UP 192.168.0.101/24 fe80::9fcd:45fb:1e0f:a1cc/64
ip -br a | awk '/wlan0/ {print $3}'
192.168.0.101/24
ip -br a | awk '/wlan0/ {print $3}' | awk -F '/' '{print $1}'
192.168.0.101
Em vez de invocar uma segunda instância de awk
(direcionando a saída de uma para a próxima); como pode ser feito de uma só vez?
Só queria dizer: a pergunta não é sobre a análise da saída de ip
. Eu só precisava de um exemplo rápido para ajudar a ilustrar a pergunta; esta foi a primeira coisa que eu fiz. A questão real é resumida no título.
De qualquer forma, vale a pena (vou ter que verificar, mas tenho certeza); isto é o que eu fiz no passado (recente):
ip -br a s dev wlan0 | awk -F '[ /]*' '{print $3}'
192.168.0.101
Você pode usar o gsub para isso:
ip -br a | awk '/wlan0/ {gsub(/\/.*/, ""); print $3}'
Basta alterar a definição de separador de campo para incluir os dois espaços e /
:
$ ip -br a | awk -F'[[:blank:]/]+' '/wlan0/{print $3}'
192.168.0.101
A opção -F'[[:blank:]/]+'
diz ao awk para usar qualquer combinação de espaços em branco, tabulações ou barras como o separador de campo na entrada.
Para essa instância, a maneira mais fácil de fazer isso provavelmente é definir vários separadores usando um regex:
ip -br a | awk -F '[\t /]*' '/wlan0/ {print$3}'
Isso torna o separador de campos qualquer string de /
, espaços ou tabulações e, em seguida, imprime o terceiro campo.
Para fazer qualquer arbitrário dois comandos que você gostaria, você praticamente precisa aprender a linguagem de programação awk completa. Eu recomendaria contra isso - tenho certeza de que você tem coisas melhores para fazer com seu tempo.
Embora as outras respostas resolvam o problema subjacente, elas realmente não respondem à pergunta: "Como faço para encadear declarações de impressão do awk?"
Para esse tipo de problema, a resposta é: "Você não faz isso". Você usa o restante da linguagem para manipular a fonte até obter o resultado desejado - que é o que as outras duas respostas fazem. Você usa somente print
para gerar o resultado final.
Depois de especificar um padrão de intervalo inicial como /wlan0/
(ou /^wl/
no meu caso porque meu WiFi tem um nome diferente), sua ação, o código dentro de {}
, só funcionará em linhas de entrada contém essa string.
Depois disso, você pode fazer o que precisar com essa linha de entrada.
ip -br a | \
awk '
/^wl/ {
ip1 = $3
gsub(/\/.*/, "", ip1)
print ip1
}
'
Esse código pega o campo desejado, coloca-o em uma variável, edita o conteúdo dessa variável e imprime-o.
A outra resposta faz a mesma coisa com mais eficiência, mas isso ilustra um caso mais geral em que outras etapas podem ser adicionadas. Você pode até salvar o resultado para usar mais tarde com algo encontrado em outra linha de entrada, etc.
Para algo que pode realmente parecer mais com "encadeamento de impressão", o awk tem uma função sprintf()
que pode fazer uma impressão formatada de sua entrada em uma variável para processamento posterior.
Ou, se você estiver imprimindo mais de uma coisa em uma linha, seu código pode usar várias declarações printf()
sem uma nova linha até a última para criar uma linha de saída peça por peça.
Isso é um pouco no espírito de A resposta de Stephen Rauch e A resposta de Joe , mas melhor:
awk '/wlan0/ {split($3, a, "/"); print a[1]}'
Isso leva o terceiro campo ( $3
) e split
s,
usando /
como o separador.
Os componentes entram no array a
e o número de subcampos é retornado.
(Neste fragmento, estou ignorando o valor de retorno.)
Portanto, a[1]
é o primeiro subcampo /
-delimited do terceiro campo.
Isso é mais facilmente generalizado do que as outras respostas. Por exemplo, se sua entrada for
Once upon a midnight dreary, while I pondered, weak and weary, Over many a quaint and curious volume of forgotten lore— wlan0 foo/bar the/quick/brown/fox/jumps/over/the lazy/dog While I nodded, nearly napping, suddenly there came a tapping, As of some one gently rapping—rapping at my chamber door.
então o comando
awk '/wlan0/ {if (split($3, a, "/") < 4) print "There is no fourth subfield";
else print "The fourth subfield is", a[4]}'
imprimirá o quarto subcampo do terceiro campo da terceira linha ( fox
),
depois de verificar o valor de retorno de split
para verificar que existem (pelo menos) quatro subcampos.
Ou seja, isso é como
awk '/wlan0/ {print $3}' | awk -F '/' '{print $4}'
em um único comando awk
, com verificação de erros.
Tags bash awk gnu bsd text-manipulation