使用 Bash 从 Cargo.toml 中提取 bin 名称

Extract bin name from Cargo.toml using Bash

我正在尝试使用 Bash 从 Cargo.toml 中提取 bin 名称,我启用了这样的 perl 正则表达式

第一次尝试

grep -Pzo '(?<=(^\[\[bin\]\]))\s*name\s*=\s*"(.*)"' ./Cargo.toml

正则表达式在regex101测试 但是一无所获

可以找到 Pzo 选项的用法 here

第二次尝试

grep -P (?<=(^[[bin]]))\n*\sname\s=\s*"(.*) " ./Cargo.toml

仍然没有

grep -Pzo '(?<=(^\[\[bin\]\]))\s*name\s*=\s*"(.*)"' ./Cargo.toml

Cargo.toml

[[bin]]
name = "acme1"
path = "bin/acme1.rs"

[[bin]]
name = "acme2"
path = "src/acme1.rs"

根据您展示的示例和尝试,请尝试使用 tac + awk 组合执行以下代码,这将更易于维护并轻松完成工作,这在 grep.

tac Input_file | 
awk '
  /^name =/{
    gsub(/"/,"",$NF)
    value=$NF
    next
  }
  /^path[[:space:]]+=[[:space:]]+"bin\//{
    print value
    value=""
  }
' | 
tac

说明:为以上代码添加详细说明。

tac Input_file |                             ##Using tac command on Input_file to print it in bottom to top order.
awk '                                        ##passing tac output to awk as standard input.
  /^name =/{                                 ##Checking if line starts from name = then do following.
    gsub(/"/,"",$NF)                         ##Globally substituting " with NULL in last field.
    value=$NF                                ##Setting value to last field value here.
    next                                     ##next will skip all further statements from here.
  }
  /^path[[:space:]]+=[[:space:]]+"bin\//{    ##Checking if line starts from path followed by space = followed by spaces followed by "bin/ here.
    print value                              ##printing value here.
    value=""                                 ##Nullifying value here.
  }
' |                                          ##Passing awk program output as input to tac here. 
tac                                          ##Printing values in their actual order.

grep:

grep -A1 '^\[\[bin\]\]$' |
grep -Po '(?<=^name = ")[^"]*(?=".*)'

或者如果你可以使用 awk,这会更健壮

awk '
 ~ /^\[\[?[[:alnum:]]*\]\]?$/{
    if (=="[[bin]]" || =="[bin]") {bin=1}
    else {bin=0}
}
bin==1 &&
sub(/^[[:space:]]*name[[:space:]]*=[[:space:]]*/, "") {
    sub(/^"/, ""); sub(/".*$/, "")
    print
}' cargo.toml

示例:

$ cat cargo.toml
[[bin]]
name = "acme1"
path = "bin/acme1.rs"

[bin]
name="acme2"

[[foo]]
name = "nobin"

    [bin]
not_name = "hello"
name="acme3"
path = "src/acme3.rs"

[[bin]]
path = "bin/acme4.rs"
name = "acme4" # a comment

$ sh solution
acme1
acme2
acme3
acme4

显然,这些不能替代真正的 toml 解析器。