Como imprimir um elemento da próxima coluna imediata correspondente depois de pesquisar o elemento na coluna atual?

0

Eu tenho milhares de linhas como visto na lista a seguir.
nome do arquivo="textfile"

3 2 3 1 4 7
5 8 6 8 9 8
8 9 4 7 3 9 
2 3 4 4 9 2 
2 2 0 9 4 0 
0 9 8 2 4 0

Eu tenho que procurar um elemento em particular - digamos, na quinta coluna - usando uma condição. (Na verdade eu tenho que encontrar o máximo.) Eu quero essa saída.  máximo da quinta coluna = 9

linha:         5 8 6 8 9 8

    2 3 4 4 9 2

Eu usei o seguinte código.

var=$(cat newfifth1 | awk 'BEGIN {max = 0} {if ($5>max) max = $5} END {print max}')
cat textfile | grep "$var" | cat $1 $2 $3 $4 $5 $6 >> newtextfile

mas isso não funciona !!!

Se possível, por favor, me dê um método mais simples e um método usando matrizes.

    
por nick ad 30.03.2015 / 07:16

2 respostas

2

De acordo com suas amostras de dados em sua pergunta, isso parece ser o que você quer (caso contrário, esclarecer sua dúvida, por favor):

awk '$5 > max { max = $5 ; out = $0 } END { print out }' datafile

Isto irá imprimir essa linha no arquivo de dados, onde o valor na quinta coluna é o máximo.

O programa funciona da seguinte maneira: Para cada linha, o quinto elemento da coluna será comparado com o máximo armazenado max (que é inicialmente 0), e se um valor maior for encontrado max recebe esse valor (para subsequente comparações) e a linha atual ( $0 ) contendo o máximo é armazenada na variável out . Como a ação final do programa, o valor da variável out será impresso.

Caso você tenha apenas valores menores que zero em seus dados, você precisará (por causa da inicialização implícita de max com zero) alguma extensão; muitas vezes é suficiente inicializar explicitamente a variável max com um valor conhecido por ser inferior aos valores nos seus dados, por ex. usando BEGIN { max = -999999 } , mas você também pode usar um padrão de código genérico da seguinte forma:

awk '(max==0 && max=="") || $5 > max { max = $5 ; out = $0 } END { print out }' datafile

Leia a parte (max==0 && max=="") da condição como: "O max ainda está indefinido?" (ou seja, ainda não é atribuído um valor).

    
por 30.03.2015 / 09:21
0

Aqui estão algumas soluções.

Duas passagens (sem matriz):

awk '
    {
        if (NR == FNR) {
                if ($5 > max) max = $5
        } else {
                if ($5 == max) print
        }
    }' textfile textfile
  • NR é o número do registro (número da linha) contado em toda a entrada. FNR é o número da linha dentro do arquivo atual . Portanto, por exemplo, se você executar awk com entrada de dois arquivos: fileC , que tem três linhas de comprimento, e fileD , que tem quatro linhas de comprimento, NR e FNR terão os seguintes valores:

    NR    FNR
     1     1
     2     2
     3     3
     4     1
     5     2
     6     3
     7     4
    

    Portanto, testar NR == FNR é um truque clássico para ver se você está olhando para o primeiro arquivo.

  • Então, o acima lê o arquivo de entrada duas vezes (você notou a última linha, onde textfile foi especificado duas vezes?). Na primeira passagem, se encontrar o valor máximo; na segunda passagem, imprime todas as linhas que contêm esse valor.

Uma passagem (usando uma matriz):

awk '
    {
        if ($5 >= max) {
                if ($5 > max) {
                        max = $5
                        delete result
                        count = 0
                }
                result[++count] = $0
        }
    }
END { for (i = 0; i <= count; i++) print result[i] }' textfile
  • Isso armazena linhas que correspondem ao valor máximo em uma matriz chamado result . Isso é complicado porque não sabemos o valor máximo até chegarmos ao fim através do arquivo (já que estamos lendo o arquivo apenas uma vez). Então, sempre que encontramos um valor maior do que qualquer um que tenhamos visto antes (ou seja, encontramos um novo máximo), limpamos ( delete ) a matriz result e recomeçamos.
  • Então, quando chegamos ao final do arquivo, imprimimos o que encontramos.

Nota: Os comandos acima falharão se cada valor na quinta coluna for ≤ 0. Para lidar com esse caso, altere if ($5 >… para if (max == "" || $5 >… em todo (incluindo o teste if ($5 >= max) ).

    
por 31.03.2015 / 06:40