# Perl one-liner for parsing host names from ssh config file

Here is the working code (intended to be executed with perl -e '<code>' ~/.ssh/config):

Actual version:

while(<>){if(/^Host (.+)/){$_=$1;foreach $i(/([^ ]+)/g){$h{$i}=1}}}print "$_ " for keys %h;


Identical version with whitespace for reading:

while(<>) {
if(/^Host (.+)/) {
$_=$1;
foreach $i(/([^ ]+)/g) {$h{$i}=1 } } } print "$_ " for keys %h;


I'm sort of a perl newbie. Is $_=$1 kosher? Is there a straight-forward way to do this with a single regex? Is there anything else I should be doing better here?

Example input output:

For a config file with contents like this:

Host build
HostName build.myserver.com
Host build build.myserver.com
User ubuntu
IdentityFile ~/.ssh/build
Host tunnel
LocalForward 6397 redis.production.com:6379


The output should be (order is not required, trailing space is not required but acceptable):

build build.myserver.com tunnel


I would use something like

perl -lane '@h{@F[1..$#F]}=()if/^Host\b/;END{$,=" ";print keys %h}' -- file


or

perl -lane '@h{ @F[ 1 .. $#F ] } = () if /^Host\b/; END {$, = " ";
print keys %h;
}' -- file

• -l removes newlines from input and adds them to prints
• -n runs the code for each line of the input
• -a splits each line on whitespace into the @F array
• the hash %h is populated by all the non-whitepsace strings following Host
• at the end, all the keys are printed separated by space
• Commenting some other things I learned from this answer that I didn't know previously: $#array returns the last index of an array, $, is the "output field separator" printed automatically between fields, END{} gives a block of code that is executed when exiting, useful for doing final one-time code while still using the -n option. – GrandOpener Jan 28 '19 at 20:22
• can shave a few characters there by switching to print "@{[ EXPR ]}" and using eof in place of an END block. And the spaces after -e and keys are optional. perl -lane'@h{@F[1..\$#F]}=()if/^Host\b/;eof&&print"@{[keys%h]}"' -- file – Oh My Goodness Jan 31 '19 at 13:21