Pretty much every time I upgrade my kernel I end up opening up the Handbook for this command, just so I don't miss any new modules. But the list it gives you is ugly, with absolute paths and .ko filename extensions. How can you make this a little easier? With a bit of logic. Behold:

This gives you a nice list of modules your kernel version can use.
How does it work? The first sed command has three parts in it's "s/.ko//"
s - substitute the text between the first set of forward slashes for the text in the second set of forward slashes.
/.ko/ - look for lines that contain this text.
// - replace .ko with the text here, in this case replace .ko with nothing.
That gets us a list of absolute pathnames without filename extensions. The second sed command uses two special characters to remove the directory names with sed 's/^.*\///'.
/^.*\// - "^" means start at the beginning of the line. "." matches any character, and "*" means patch the preceding (any) character zero or more times. The "/" we are looking for (the last "/" in the line) is escaped with "\" because "/" has special meaning to the sed program and most GNU-style regular expression handling.
It appears that the default behaviour of sed searches right to left; I'm sure there is a way to change that, but in this case it works.
Now you have a list of filenames, but they are all on one line. I couldn't think of an existing Linux command that would combine these into a single line, so I wrote one in Perl:

Code:

#!/usr/bin/perl -w

my @strings;

while ($in = <>)
{
push (@strings, $in);
}

foreach $s (@strings)
{
chomp($s);
print $s . " ";
}

print "\n";

Simply save to a .pl file and chmod a+x. I copied this program to /usr/local/bin/oneline.pl. Now you have a quick an easy method to grab all those modules to /etc/conf.d/modules.

I find it vaguely unsettling that a Cisco-certified individual would take such a long way to achieve such a simple result, especially since you then go on to explain sed regular expressions in detail. Even setting aside the nice rewrite that khayyam gave you, there are better ways to do what you want.

Now you have a list of filenames, but they are all on one line. I couldn't think of an existing Linux command that would combine these into a single line

According to the documentation, xargs has an implicit command of /bin/echo when invoked without an explicit command. You could also use xargs printf '%s ', though that is somewhat longer. For some unusual inputs, you may need to use xargs -d'\n'.

wjholden wrote:

so I wrote one in Perl:

Code:

#!/usr/bin/perl -w

You missed both use strict; and use warnings FATAL => qw(all);. You enabled warnings, which is good, but you did not make them fatal.

wjholden wrote:

Code:

my @strings;

while ($in = <>)
{
push (@strings, $in);
}

foreach $s (@strings)
{
chomp($s);
print $s . " ";
}

Why build a temporary array just to print it back? Chomp the lines as you get them, and print them on the spot.

Code:

while(<>){chomp;print "$_ ";}

You could avoid one sed transform and the use of the oneline.pl script with a good use of -printf:

Code:

find /lib/modules/$(uname -r) -type f -name '*.ko' -printf '%f '

[Edit: my initial advice used the wrong format specifier in the find -printf that I recommended. The correct specifier for this usage is %f, not %P as I originally stated.]