从 ~/.ssh/config— 打印别名,带或不带尾随连字符



我有以下文件,它是ssh的配置文件。

Host vps2 # Linode
HostName xxx.xx.xx.xxx
User foo_user
Host vps3 # Vultr
HostName xxx.xx.xx.xxx
User foo_user   
Host vps4
HostName xxx.xx.xx.xxx
User foo_user
Host vps5
HostName xxx.xx.xx.xxx
User foo_user 
Host vps6
HostName xxx.xx.xx.xxx
User foo_user 
Host vps7 # DigitalOcean
HostName xxx.xx.xx.xxx
User foo_user
Host vps8 # GCP
HostName xxx.xx.xx.xxx
User foo_user   
Host pi
HostName xxx.xx.xx.xxx
User pi
# OLD SHALL NOT BE USED
Host vps13
HostName xxx.xx.xx.xxx
User foo_user
Host vps14-old
HostName xxx.xx.xx.xxx
User foo_user 
Host vps4-old
HostName xxx.xx.xx.xxx
User foo_user 
Host vps15-old
HostName xxx.xx.xx.xxx
User foo_user 
Host vps11-old
HostName xxx.xx.xx.xxx
User foo_user

我需要打印以vps*开头的别名,下面的(复制的)片段将完全做到这一点。

$ awk '{for(i=1;i<=NF;i++){if($i~/^vps/){print $i}}}' $HOME/.ssh/config
vps2
vps3
vps4
vps5
vps6
vps7
vps8
vps3-old
vps4-old
vps5-old
vps11-old

现在我想打印所有没有-old后缀的别名,添加| grep -v old工作。

$ awk '{for(i=1;i<=NF;i++){if($i~/^vps/){print $i}}}' $HOME/.ssh/config | grep -v "old"
vps2
vps3
vps4
vps5
vps6
vps7
vps8

有没有更清洁的方法?最好只涉及 1 个工具,我尝试使用awk命令无济于事。

您可以使用sed,如果您使用支持比grep更扩展的正则表达式的-n(无打印),它具有类似 grep 的模式。过滤掉以-old结尾的行的技巧在这里找到:Sed 正则表达式和子字符串否定:

sed -n "/-old/b; s/^Hosts+(vpsS*)s*(#.*)?/1/p" $HOME/.ssh/config

逆向(包括-old)更简单一些,因为它只需要正匹配:

sed -n "s/^Hosts+(vpsS*-old)s*(#.*)?/1/p" $HOME/.ssh/config

您可以向awk命令添加$i!~/-old$/条件:

awk '{for(i=1;i<=NF;i++){if($i~/^vps/ && $i!~/-old$/){print $i}}}' ~/.ssh/config

(注意:当它不在双引号中时,我更喜欢~而不是$HOME,以防路径中有奇怪的字符。

这可能对你有用(GNU sed):

sed -En '/-old/!s/^Hosts*(vpsS*).*/1/p' file

使用-n-E选项关闭隐式打印和扩展正则表达式。

如果一行不包含-old,则匹配以Host开头的行,后跟一些空格,后跟vps,后跟零个或多个非空格,后跟任何内容,并将其替换为vps后跟任何非空格并打印结果。

要仅显示包含-old的行,请使用:

sed -En '/-old/s/^Hosts*(vpsS*).*/1/p' file

注:注:这依赖于不包含注释或多个主机名的Host行。

Idk 为什么当你想要的字符串总是在以Host开头的行的第二个字段中时循环:

$ awk '/^Host vps/ && !/-old/{ print $2 }' file
vps2
vps3
vps4
vps5
vps6
vps7
vps8
vps13

我在评论中看到您实际上希望输出全部在 1 行上,那就是:

$ awk '/^Host vps/ && !/-old/{ printf "%s%s", sep, $2; sep=OFS } END{print ""}' file
vps2 vps3 vps4 vps5 vps6 vps7 vps8 vps13
grep -Po '(?<=Host )vpsd+(?!-old)' file | sort -uV

最新更新