awk + imprime todo o conteúdo da linha, exceto $ 1

3

Eu escrevo o seguinte script awk:

% echo /var/sysconfig/network/my_functions  alpha beta gama  | \
      awk -v word=alpha '$2  == word { print $0 }'

como dizer ao awk que eu quero imprimir todas as linhas, exceto $ 1 (/ var / sysconfig / network / my_functions PATH), então vou pegar o seguinte:

alpha beta gama

em vez de

/var/sysconfig/network/my_functions alpha beta gama

observação : o conteúdo da linha pode ser qualquer coisa e não é limitado por strings / quantidade de palavras

    
por jennifer 21.11.2010 / 13:21

7 respostas

1

Eu acho que no awk não há como remover o primeiro campo manualmente. (Existem outras maneiras se você estiver disposto a normalizar o espaço entre campos).

awk '$2 == word {match($0, "("FS")+"); print substr($0, RSTART+RLENGTH);}'
    
por 21.11.2010 / 17:06
5

Se você definir $1 para "" , sairá do espaço delimitador. Se você não quiser fazer isso, terá que fazer uma iteração nos campos:

awk '{for (f=2; f<=NF; ++f) { if (f!=2) {printf("%s",OFS);} printf("%s",$f)}; printf "\n" }'

Editar: corrigido por comentário de Gilles.

Outra maneira de fazer a mesma coisa:

awk '{d = ""; for (f=2; f<=NF; ++f) {printf("%s%s", d, $f); d = OFS}; printf("\n") }'
    
por 21.11.2010 / 16:44
2

De alguma forma, acho que isso seria muito mais fácil e intuitivo com o comando cut:

echo /var/sysconfig/network/my_functions  alpha beta gama | cut -d' ' -f 2-

O único problema é que o corte não suporta vários tipos diferentes de espaços em branco de uma só vez para delimitadores. Então, se você tiver espaços ou guias, não funcionará.

    
por 21.11.2010 / 16:32
1
 % echo /var/sysconfig/network/my_functions  alpha beta gama | \
      awk -v word=alpha \
             '$2 == word { $1=""; print $0 }'
    
por 21.11.2010 / 14:04
1

Esta solução (um pouco complicada) que é um pouco semelhante à resposta de Gilles ,

  • não gera espaço no início da linha,
  • manipula corretamente o caso em que a linha de entrada começa com espaço em branco e
  • preserva o espaço em branco entre campos.
awk -v word=alpha '
    $2 == word {
        i = index($0, $1)               # Find $1 within $0 (the line).
        if (i > 0) {                    # Sanity check; should always be true.
                i = i + length($1)      # Find space after $1.
                temp = substr($0, i)
                i = index(temp, $2)     # Find $2 in remainder of line.
                if (i > 0) {            # Sanity check; should always be true.
                        print substr(temp, i)
                }
        }
    }'

Eu acredito que os comentários em linha explicam isso muito bem. Encontramos a posição $1 na linha (lembre-se de que não estou assumindo explicitamente que isso está no começo). Então, à la resposta de Gilles , nós removemos $1 (e o espaço em branco antes, se houver) da linha. Em seguida, localize a posição de $2 no restante da linha, e retirar o espaço antes disso.

Aqui está uma pequena simplificação da resposta de Dennis Williamson .

awk -v word=alpha '$2==word { for (f=2; f<=NF; ++f) printf("%s%s", $f, (f==NF?ORS:OFS)) }'

Como a resposta de Dennis, ele gera os campos $2 , $3 ,…, $NF (omitindo $1 ) com separação padrão. Dennis levou a aproximação do anterior $3 ,…, $NF (mas não $2 ) com o separador de campos de saída padrão. Eu usei a abordagem após $2 , $3 ,…, $(NF-1) (mas não $NF ) com o OFS. E, como $NF é seguido pelo separador record (ORS) de saída, podemos usar um operador ?: sem termos nulos, e elimine o% finalprintf("\n").

    
por 16.01.2017 / 05:43
-1

Todos sempre tornam mais difícil do que é

$ echo /var/sysconfig/network/my_functions alpha beta gama |
awk -v word=alpha '$2==word{print substr($0,index($0,$2))}'
alpha beta gama
    
por 28.12.2012 / 20:48
-1

Use isto se você quiser mudar o delimitador. Meu delimitador é "|":

awk -F '|' '{d = ""; for (f=2; f<=NF; ++f) {printf("%s%s", d, $f); d = OFS}; printf("\n") }'
    
por 19.12.2016 / 12:11

Tags