Como eu combino as opções -v e -B no grep?

5

Eu tenho uma lista de kernels atualmente instalados, e estou tentando encontrar tanto o kernel atualmente instalado quanto o kernel previamente instalado. Para este exemplo, o linux-image-3.2.0-60-generic é o kernel atualmente em execução, e estes são os kernels instalados:

linux-image-3.2.0-49-generic
linux-image-3.2.0-51-generic
linux-image-3.2.0-52-generic
linux-image-3.2.0-53-generic
linux-image-3.2.0-54-generic
linux-image-3.2.0-55-generic
linux-image-3.2.0-56-generic
linux-image-3.2.0-57-generic
linux-image-3.2.0-58-generic
linux-image-3.2.0-59-generic
linux-image-3.2.0-60-generic
linux-image-3.2.0-61-generic
linux-image-3.2.0-63-generic
linux-image-3.2.0-64-generic

Eu posso usar grep -v $(uname -r) para remover o kernel atualmente em execução desta lista. No entanto, não consigo usar grep -v -B 1 $(uname -r) para remover o kernel atual e o anterior da lista. Existe uma maneira de combinar o -B e o -v ? Ou estou me aproximando disso inteiramente da direção errada?

    
por zymhan 06.06.2014 / 22:02

3 respostas

2

Você pode usar 2 grep para conseguir o que deseja. O interior grep gerará a "lista" de correspondências para o kernel atual, uname -r e a reversão anterior para ele. O exterior grep dará a lista de kernels excluindo estes 2.

$ grep -v "$(grep -B 1 "$(uname -r)" list.txt)" list.txt

Exemplo

Para simular o que você tem, eu adicionei o conteúdo deles ao arquivo list.txt .

$ cat list.txt 
linux-image-3.2.0-49-generic
linux-image-3.2.0-51-generic
linux-image-3.2.0-52-generic
linux-image-3.2.0-53-generic
linux-image-3.2.0-54-generic
linux-image-3.2.0-55-generic
linux-image-3.2.0-56-generic
linux-image-3.2.0-57-generic
linux-image-3.2.0-58-generic
linux-image-3.2.0-59-generic
linux-image-3.2.0-60-generic
linux-image-3.2.0-61-generic
linux-image-3.2.0-63-generic
linux-image-3.2.0-64-generic

Agora vamos fingir que o comando uname -r retorna esta string:

$ uname -r
3.2.0-60-generic

Então, quando eu executo este comando, eu obtenho uma lista dos kernels menos o uname -r e a versão anterior a ele.

$ grep -v "$(grep -B 1 "3.2.0-60-generic" list.txt)" list.txt 
linux-image-3.2.0-49-generic
linux-image-3.2.0-51-generic
linux-image-3.2.0-52-generic
linux-image-3.2.0-53-generic
linux-image-3.2.0-54-generic
linux-image-3.2.0-55-generic
linux-image-3.2.0-56-generic
linux-image-3.2.0-57-generic
linux-image-3.2.0-58-generic
linux-image-3.2.0-61-generic
linux-image-3.2.0-63-generic
linux-image-3.2.0-64-generic

Isso tudo assume que a lista de kernels em list.txt está em um formato classificado.

Dicas adicionais

Se você tiver interesse, escrevi um A para este P & A intitulado: Como determinar programaticamente a versão mais alta do kernel RPM instalado? onde mostro como você pode analisar versões de kernels usando sort -V .

    
por 07.06.2014 / 00:40
1

Como você mencionou a lista, presumo que esteja em algum arquivo. No entanto, o comando pode ser facilmente modificado.

Uma abordagem mais simples seria

current_ver=$(uname -r)
awk "/$current_ver/{y=1;next}y" list

A variável current_ver armazena a versão atual do kernel. O comando awk obtém a saída após a versão atual.

P.S:

Eu não sou muito versado em awk . O comando pode ser melhorado ainda mais:)

    
por 06.06.2014 / 22:35
1

Como estamos definitivamente trabalhando com o linux, você pode usar os resultados de classificação do GNU ls to -v ersion. Considerando que e que seus nomes de arquivos do kernel provavelmente não contêm nenhum caractere estranho que você possa fazer:

ls -1v /boot/linux-image* | grep "$(uname -r)" -B1
    
por 07.06.2014 / 02:27

Tags