5

I have a list of currently installed kernels, and I'm trying to grep out both the currently installed kernel and the previously installed kernel. For this example, linux-image-3.2.0-60-generic is the currently running kernel, and these are the installed kernels:

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

I can use grep -v $(uname -r) to remove the currently running kernel from this list. However, I can't seem to use grep -v -B 1 $(uname -r) to remove current and previous kernel from the list. Is there a way to combine the -B and -v? Or am I approaching this entirely from the wrong direction?

  • 1
    -B N means to print N lines before the lines that are printed. When used with -v, it means to print lines before the lines that DON'T match. Which basically means that it will N lines that match the regexp before each non-matching line. – Barmar Jun 6 '14 at 20:06
  • I think you should be able to do what you want with awk pretty easily. Save the previous line in a variable. When you read a line that doesn't match the current version, print the saved line, and put the current line in the variable. When you read a line that DOES match the current version, clear the variable and don't print anything. Finally, print the saved line in the END block. – Barmar Jun 6 '14 at 20:09
  • From where you get the list of kernels as output? Is it from any file? – Ramesh Jun 6 '14 at 20:30
  • No, it's from some crazy grepping: dpkg -l linux-image-[0-9]* | grep "ii " | grep -oE linux-image-[a-zA-Z0-9.\-]\{0,\}. This only works on Debian-based systems, of course. – zymhan Jun 6 '14 at 21:12
2

You can use 2 grep's to get what you want. The interior grep will generate the "list" of matches for the current kernel, uname -r and the previous reversion to it. The exterior grep will give you the list of kernels excluding these 2.

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

Example

To simulate what you have I've added the contents of these to the file 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

Now let's pretend that the command uname -r returns this string:

$ uname -r
3.2.0-60-generic

So when I run this command I get a list of the kernels minus the uname -r and the version previous to it.

$ 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

This all assumes that the list of kernels in list.txt is in a sorted format.

Additional tips

If you're interested, I wrote up a A to this Q&A titled: How to programmatically determine the highest version kernel RPM installed? where I show how you can parse out versions of kernels using sort -V.

1

As you have mentioned the list, I assume it is in some file. Nevertheless, the command can be easily modified.

A simpler approach would be,

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

The current_ver variable stores the current kernel version. The awk command gets the output after the current version.

P.S:

I am not pretty well versed in awk. The command can sure be further enhanced :)

1

Since we are definitely working with linux here you might use GNU ls to -version sort results. Considering that and that your kernel file-names are unlikely to contain any weird characters you could do:

ls -1v /boot/linux-image* | grep "$(uname -r)" -B1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.