在 bash 中搜索 .netrc 文件,并为给定机器搜索 return 用户名

Search .netrc file in bash, and return username for given machine

我需要一种方法 (最便携的) 在 bash 中执行搜索 ~/.netrc 文件的特定 machine api.mydomain.com 然后在下一行,提取用户名值。

格式为:

machine a.mydomain.com
  username foo
  passsword bar
machine api.mydomain.com
  username boo
  password far
machine b.mydomain.com
  username doo
  password car

因此,它应该与此示例中的 api.mydomain.com 和 return 完全匹配 boo

awk '/api.mydomain.com/{getline; print}' ~/.netrc

获取我想要的行,但如何找到用户名值?

您可以执行以下操作:

 awk '/api.mydomain.com/{getline;print }' ~/.netrc ## will print username
$ awk '/api.mydomain.com/{getline; print }' ~/.netrc
boo

要在变量中捕获它:

$ name=$(awk '/api.mydomain.com/{getline; print }' ~/.netrc)
$ echo "$name"
boo

默认情况下,awk 根据空格将记录(行)拆分为字段。因此,在行 username boo 上,username 被分配给字段 1,表示为 </code>,而 <code>boo 被分配给字段 2,表示为

如果您想避免使用 getline 函数,请使用:

awk '/api.mydomain.com/ {f=NR} f&&f+1==NR {print }' ~/.netrc
boo

正如 Ed 在这里所写:避免使用它。
http://awk.info/?tip/getline

这会找到模式的行号,然后
当行号多一个时,打印字段 #2

可以缩短为:

awk '/api.mydomain.com/ {f=NR} f&&f+1==NR&&[=11=]=' ~/.netrc

awk 'f&&!--f&&[=12=]=; /api.mydomain.com/ {f=1}' ~/.netrc

这可能是最稳健的方法。
如果域后有注释行或空行,则其他解决方案失败。

awk '/api.mydomain.com/ {f=1} f && /username/ {print ;f=0}' ~/.netrc
boo

如果找到域,设置标志 f。如果标志 f 为真并且下一行有 username 打印字段 #2

这个 sed 非常便携:

sed -n '
    /machine[   ]\{1,\}api.mydomain.com/ {      
        # we have matched the machine
        :a
        # next line
        n
        # print username, if matched
        s/^[    ]\{1,\}username[        ]\{1,\}//p
        # goto b if matched
        tb
        # else goto a
        ba
        :b
        q
    }
' ~/.netrc

括号里的白色space是一个space和一个制表符


用新的眼光看待这个,这就是我现在要写的:

awk -v machine=api.mydomain.com '
     == "machine" {
        if (m)
            # we have already seen the requested domain but did not find a username
            exit 1
        if ( == machine) m=1
    }
    m &&  == "username" {print ; exit}
' ~/.netrc

或者如果你喜欢难读的单行本

awk '=="machine"{if(m)exit 1;if(==M)m=1} m&&=="username"{print ;exit}' M=api.mydomain.com ~/.netrc

这个 vanilla Bourne shell(包括 Bash、KSH 等)函数应该解析任何有效的 .netrc 文件:它处理了我能想到的一切。使用 netrc-fetch MACHINE [FIELD] 调用。对于你的问题,它将是 netrc-fetch api.mydomain.com user.

netrc-fetch () {
  cat $HOME/.netrc | awk -v host= -v field=${2:-password} '
    {
      for (i=1; i <= NF; i += 2) {
        j=i+1;
        if ($i == "machine") {
          found = ($j == host);
        } else if (found && ($i == field)) {
          print $j;
          exit;
        }
      }
    }
  '
}