Extrai o 'm'th (primeiro) valor da coluna para a linha com o valor da coluna' n'th (second) específico do arquivo [duplicate]

5

Eu preciso escrever um comando awk que retornará o número de identificação da tabela a seguir apenas para as linhas em que o título é Turtle . Esta tabela é armazenada em turtle.txt

Id Num. Title           CatchDate
433417  RedTurtle       2001-06-29
493303  BlueTurtle      1998-09-20
259497  Turtle          1985-05-08
229505  RedTurtle       1994-07-13
473076  OrangeTurtle    2002-03-08
221907  Blueturtle      1999-07-02
457032  Turtle          1993-04-09
490359  RedTurtle       1996-11-12
494595  SnappingTurtle  1985-05-20
402421  BlueTurtle      1999-08-16
    
por Isaac 08.10.2018 / 14:34

6 respostas

5

com o awk:

$ awk '$2 == "Turtle" {print $1}' turtle.txt
259497
457032
  • $2 é o campo a ser selecionado.
  • Turtle é o texto para correspondência.
  • {print $1} é imprimir o primeiro campo.
  • turtle.txt é o nome do arquivo de origem.

com sed:

$ <infile sed -E 's/[[:blank:]]+/\n/g;/([^\n]+\n){1}Turtle/([^\n]*).*//;p};d'

Explicado:

  • <infile Arquivo de origem
  • sed -E Use sed com POSIX ERE (Extended Express Expresions)
  • 's/[[:blank:]]+/\n/g Substitua tudo (executa + ) do espaço de tabulação por uma nova linha.
  • /([^\n]+\n){1}Turtle\n/ Se o campo n (use n-1 here) corresponde a Turtle (exatamente).
  • ([^\n]*).*// Extrair campo 1 (primeira linha)
  • p};d' Imprime o que foi selecionado e exclui tudo em qualquer caso.

Solução geral para qualquer par de campos n e m :

<infile sed -E 's/[[:blank:]]+/\n/g;/([^\n]+\n){1}Turtle/{s/([^\n]+\n){0}([^\n]*).*//;p};d'
  • <infile Arquivo de origem
  • sed -E ' Para sed com regexes ERE.
  • s/[[:blank:]]+/\n/g Divide todas as entradas em linhas em (execuções) de tabulações ou espaços.
  • /([^\n]+\n){1}Turtle/ Se o espaço do padrão corresponder ao campo n th (use n-1 ( {1} ) aqui).
  • { Inicia uma sequência de comandos.
  • s/ Inicia uma substituição (um comando s/// ).
  • ([^\n]+\n){0} Coincidir m-1 ( {0} ) linhas (para o campo m ).
  • ([^\n]*) Capture o campo (a linha) para manter a referência de referência .
  • .* E corresponde a todo o resto (no espaço padrão (a linha original)).
  • // Substitua todos acima (O espaço de padrão) pelo que foi capturado em .
  • ;p}; Imprima. E feche a sequência de comandos.
  • d Em qualquer caso, exclua o espaço do padrão e comece novamente.
  • ' Comando finalizar sed.
por 08.10.2018 / 14:36
4

Você pode usar:

awk '$2 == "Turtle" {print $1}' file
259497
457032
    
por 08.10.2018 / 14:37
3

Usando sed:

sed -n '/\sTurtle\s/s/^\([0-9]\+\)\s.*//p' file
    
por 08.10.2018 / 14:46
2

alternativa não-awk:

grep -w "Turtle" turtle.txt | cut -d " " -f 1

    
por 08.10.2018 / 14:38
2

Golfando :

$ awk '$2=="Turtle"&&$0=$1' <file
259497
457032

Ou, expandido em etapas até chegarmos às respostas de Isaac e Goro

awk '$2 == "Turtle" && $0 = $1' <file

awk '$2 == "Turtle" { $0 = $1; print }' <file

awk '$2 == "Turtle" { print $1 }' <file

Os três não são exatamente equivalentes, pois meu código golfed não imprimiria o número se fosse zero (o resultado de $0=$1 é usado como condicional).

Aqui está uma solução sed adequada para compensar o golfe acima:

$ sed -n '/\<Turtle\>/s/[[:blank:]].*//p' <file
259497
457032

Ele encontra todas as linhas contendo a palavra Turtle e, em seguida, remove o primeiro espaço ou caractere de tabulação e tudo após ele nessas linhas antes de imprimi-las (a impressão de outras linhas é inibida por -n ).

O \< e o \> correspondem aos limites inicial e final da palavra, de forma que \<Turtle\> corresponde apenas à sequência Turtle e não, por exemplo, RedTurtle .

    
por 08.10.2018 / 15:03
1

Você pode empregar grep nisso:

 grep -oP '^\d+(?=\h+Turtle\h)'
    
por 08.10.2018 / 17:13