Não tenho certeza de por que isso tem 87 votos positivos, certamente pode ser melhorado com um exemplo, no mínimo.
Arj
Provavelmente porque a pergunta é extremamente simples por natureza e facilmente compreendida sem um exemplo, o que é raro, mas neste caso parece funcionar. O problema aqui não é falta de informação eu acho, mas mais que mostra falta de pesquisas independentes.
DryLabRebel
Esta pergunta também é uma duplicata desta pergunta.
Você precisa de uma vírgula - já que estamos sendo exigentes hoje: o espaço concatena os campos, a vírgula separa os campos em uma instrução de impressão. Isso unirá os dois campos
Jim Mcnamara
18
Agora você está imprimindo "campo-OFS-guia-campo-OFS". Deve ser awk '{print $(NF-1) "\t" $NF}' fileou awk '{print $(NF-1), $NF}' fileou awk 'BEGIN{OFS="\t"} {print $(NF-1), $NF}' file.
Pausado até novo aviso.
Apenas para adicionar ao comentário anterior, o problema de usar '{print $x,"\t",$y}'é que awk interpreta cada variável separada por vírgula como seu próprio campo, então o resultado será field1<space><tab><space>field2, (porque ele usará delimitador de espaço em branco por padrão) ao contrário do field1<tab>field2que provavelmente é o que você está esperando. usar o separador de campo de saída (OFS) é quase sempre o que você deseja.
DryLabRebel
13
awk '{print $NF-1, $NF}' inputfile
Nota: isso funciona apenas se houver pelo menos duas colunas. Em registros com uma coluna, você obterá um espúrio"-1 column1"
Experimente e veja. Ele funciona no Solaris 9 awk e nawk. A alternativa é $ (NF-1)
jim mcnamara
1
@coaddict - Suponho que você não trabalhou com diferentes implementações do awk. Antigos comportamentos de awks foram (talvez erroneamente) apresentados. Não tenho gawk para testar - que é provavelmente o que você está se referindo. Portanto, não sei ao certo por que seu comentário veio abnput. O Linux fora da caixa geralmente é estúpido. Vou testar e postar de volta. Enquanto isso, tente Soalris ou HPUX ou DGX ou qualquer outra coisa para ver o que quero dizer com antigo awk.
Jim Mcnamara
6
Você provavelmente foi levado a pensar que funcionou porque tentou echo 1 2 3 | awk .... $NF-1está ($NF) - 1em cada awkimplementação.
Stephane Chazelas
O código-fonte "One True Awk" tem mais de 40 conflitos na yaccgramática, o que é irônico dado o que o A significa em awk. Versões diferentes do awk analisando as coisas de maneira diferente? Grande surpresa!
Kaz
1
@THESorcerer, tente com echo '5 4 3 2 1' | awk '{print $NF-1,$NF; print $(NF-1), $NF}'- ou qualquer outra entrada onde o segundo último campo não seja um a menos que o último campo.
glenn jackman
6
@jim mcnamara: tente usar parênteses ao redor NF, ou seja, $(NF-1)e ao $(NF)invés de $NF-1e $NF(funciona no Mac OS X 10.6.8 para FreeBSD awke gawk).
echo '
1 2
2 3
one
one two three
'| gawk '{if (NF >= 2) print $(NF-1), $(NF);}'# output:# 1 2# 2 3# two three
Já havíamos considerado () anteriormente. Achei que estávamos discutindo de onde veio o antigo comportamento original do awk.
Jim Mcnamara,
+1 para uma resposta com explícito $(NF-1)- que no mínimo é mais portátil do que $NF-1; é definitivamente menos ambíguo. $(NF)é um exagero - apenas $NFservirá. Também vale a pena se proteger contra linhas com menos de 2 colunas, pois com linhas de uma coluna você obteria o valor da primeira coluna duas vezes , e com linhas zero - ou seja, vazias - o comando awk falharia completamente, devido a uma tentativa para acessar um campo com índice -1.
mklement0
1
usar o gawk exibe o problema:
gawk '{ print $NF-1, $NF}' filename1223-1 one-1 three# cat filename1223
one
one two three
Acabei de colocar gawk no Solaris 10 M4000: Então, gawk é o cuplrit na questão $ NF-1 vs. $ (NF-1). Próxima pergunta, o que POSIX diz? por:
As primeiras 2 linhas de seu arquivo de entrada de amostra não são úteis porque produzem a mesma saída com qualquer um dos comportamentos. Você pode reconfirmar que o Solaris awk realmente NÃO se comporta como gawk neste caso?
mklement0
Quanto ao seu link para a especificação do awk: O argumento anedótico para usar $(NF-1)é que os dois exemplos de cálculo do índice de campo na especificação usam essa forma: $(NF-1)e $(NF+2). Depois, há a seção "Expressões no awk", que lista os $exprnomes com precedência [muito] maior do que expr - expr. Uma vez que NFé uma expressão em si, $NF-1deve avaliar como ($NF)-1. Mesmo se, afinal, houver implementações awk por aí que avaliam $NF-1como $(NF-1), a lição aprendida aqui é que usar $(NF-1)é a escolha segura e portátil.
Respostas:
Você pode usar a variável
NF
que é definida como o número total de campos no registro de entrada:isso pressupõe que você tenha pelo menos 2 campos.
fonte
awk '{print $(NF-1) "\t" $NF}' file
ouawk '{print $(NF-1), $NF}' file
ouawk 'BEGIN{OFS="\t"} {print $(NF-1), $NF}' file
.'{print $x,"\t",$y}'
é que awk interpreta cada variável separada por vírgula como seu próprio campo, então o resultado seráfield1<space><tab><space>field2
, (porque ele usará delimitador de espaço em branco por padrão) ao contrário dofield1<tab>field2
que provavelmente é o que você está esperando. usar o separador de campo de saída (OFS) é quase sempre o que você deseja.Nota: isso funciona apenas se houver pelo menos duas colunas. Em registros com uma coluna, você obterá um espúrio
"-1 column1"
fonte
echo 1 2 3 | awk ...
.$NF-1
está($NF) - 1
em cadaawk
implementação.yacc
gramática, o que é irônico dado o que o A significa em awk. Versões diferentes do awk analisando as coisas de maneira diferente? Grande surpresa!echo '5 4 3 2 1' | awk '{print $NF-1,$NF; print $(NF-1), $NF}'
- ou qualquer outra entrada onde o segundo último campo não seja um a menos que o último campo.@jim mcnamara: tente usar parênteses ao redor
NF
, ou seja,$(NF-1)
e ao$(NF)
invés de$NF-1
e$NF
(funciona no Mac OS X 10.6.8 para FreeBSDawk
egawk
).fonte
$(NF-1)
- que no mínimo é mais portátil do que$NF-1
; é definitivamente menos ambíguo.$(NF)
é um exagero - apenas$NF
servirá. Também vale a pena se proteger contra linhas com menos de 2 colunas, pois com linhas de uma coluna você obteria o valor da primeira coluna duas vezes , e com linhas zero - ou seja, vazias - o comando awk falharia completamente, devido a uma tentativa para acessar um campo com índice -1.usar o gawk exibe o problema:
Acabei de colocar gawk no Solaris 10 M4000: Então, gawk é o cuplrit na questão $ NF-1 vs. $ (NF-1). Próxima pergunta, o que POSIX diz? por:
Não há direção de um jeito ou de outro. Não é bom. gawk implica subtração, outros awks implicam número de campo ou subtração. Hmm.
fonte
$(NF-1)
é que os dois exemplos de cálculo do índice de campo na especificação usam essa forma:$(NF-1)
e$(NF+2)
. Depois, há a seção "Expressões no awk", que lista os$expr
nomes com precedência [muito] maior do queexpr - expr
. Uma vez queNF
é uma expressão em si,$NF-1
deve avaliar como($NF)-1
. Mesmo se, afinal, houver implementações awk por aí que avaliam$NF-1
como$(NF-1)
, a lição aprendida aqui é que usar$(NF-1)
é a escolha segura e portátil.tente com isso
fonte
Tente fazer isso levando em consideração todos os cenários possíveis:
ou
ou
fonte