Erro de sintaxe removendo linhas duplicadas via arquivo awk '! x [$ 0] ++'

4

O arquivo contém

cat file
a
b
c
b
d

Tentando remover linhas duplicadas no SunOS via

awk '!x[$0]++' file

(como encontrado em outras postagens) resulta em um erro de sintaxe

awk: syntax error near line 1
awk: bailing out near line 1

O que eu sinto falta?

    
por nickm 07.02.2016 / 10:37

1 resposta

5

awk foi lançado pela primeira vez no final dos anos 70 no Unix V7.

Desde então, sofreu mudanças significativas, algumas não compatíveis com versões anteriores.

O manual GNU awk tem uma seção muito informativa sobre o assunto .

Como para muitos outros utilitários, o Solaris (ao contrário da maioria dos outros Unices) assumiu a postura de aderir à implementação obsoleta mais antiga para seu utilitário awk padrão e disponibilizar as versões mais recentes com um nome diferente ( nawk ) ou em um local diferente ( /usr/xpg4/bin/awk , aquele não disponível por padrão em algumas configurações despojadas do Solaris 11).

No Solaris, se você usa o ambiente padrão, geralmente obtém utilitários que se comportam de uma maneira antiga / obsoleta. Por exemplo, antes do Solaris 11, sh no ambiente padrão não seria um shell padrão, mas um shell Bourne. Muitos outros utilitários ( grep , sed , tail , df ...) não são compatíveis com POSIX, nem mesmo para a versão de 1992 do padrão.

O Solaris é um sistema certificado POSIX (até mesmo Unix) (pelo menos em algumas configurações), porém o POSIX / Unix requer apenas que um sistema seja compatível em um determinado ambiente (documentado) (que pode não ser o padrão).

Então, quando você escreve um código que precisa ser portátil para o Solaris, você precisa escrever uma sintaxe de outra idade, ou ter certeza de colocar-se em um ambiente POSIX.

Como fazer isso para uma determinada versão desses padrões está documentada na página standards(5) man no Solaris.

Então, para awk aqui, você pode usar:

awk 'x[$0]++ == 0'

O que funcionaria em 1978 awk do Unix v7 e Solaris /bin/awk (no original awk , você não podia usar qualquer expressão arbitrária como um padrão , ele tinha que ser condições usando operadores relacionais como == aqui.

Ou:

nawk '!x[$0]++'

Ou:

/usr/xpg4/bin/awk '!x[$0]++'

Em geral, para ter versões mais seguras (e mais portáteis) de todos os utilitários (incluindo awk ):

PATH='getconf PATH':$PATH export PATH
: ^ false || exec sh "$0" ${1+"$@"} # rexec with POSIX sh if we're
                                    # a Bourne shell
awk '!x[$0]++'

Tanto /usr/bin/getconf PATH como /usr/xpg4/bin/getconf PATH fornecerão um $PATH como /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin , o que lhe dará XPG4 (um superconjunto de POSIX.1-1990, POSIX.2-1992 e POSIX.2a- 1992) conformidade. No Solaris 11, você também tem um /usr/xpg6/bin/getconf que lhe dará uma PATH como /usr/xpg6/bin:/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin para a conformidade com XPG6 (SUSv3, superconjunto de POSIX 2001) (onde conflitar com XPG4, na prática provavelmente não afetará você). / p>     

por 08.02.2016 / 15:12

Tags