在bash函数中访问命令行参数?

chi*_*aku 2 bash shell function command-line-arguments

我正在尝试访问下面函数中的命令行参数,但我无法让它工作.我认为它与报价有关,但我无法弄明白.

search_second_line() {
    awk 'FNR==2 {if (/$1)/) print FILENAME; nextfile}' ./*
}
alias st="search_second_line"
Run Code Online (Sandbox Code Playgroud)

Joh*_*024 5

这将有效(但你必须小心你用于参数):

st() { awk "FNR==2 {if (/$1/) print FILENAME; nextfile}" ./*; }
Run Code Online (Sandbox Code Playgroud)

这里的危险是$1成为代码的一部分,如果它包含awk-active字符,可能会做出令人惊讶的事情.

这有点安全:

st() { awk -v c="$1" 'FNR==2 {if ($0 ~ c) print FILENAME; nextfile}' ./*; }
Run Code Online (Sandbox Code Playgroud)

在这里,我们将awk传递给c具有内容的变量$1.awk会知道将其c视为变量,而不是代码.

这与上面相同,但它简化了逻辑:

st() { awk -v c="$1" 'FNR==2 && $0~c {print FILENAME; nextfile}' ./*; }
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • -v c="$1"

    这定义了awk变量c.这是从shell传递信息最可靠的awk.

  • FNR==2 && $0~c {print FILENAME; nextfile}

    这将应用两个条件并在执行print/ nextfilestatement 之前一起使用.第一个要求这是第二行.第二个要求此行匹配c.

外壳和引用

单引号和双引号之间的差异可以在命令行中轻松演示.尝试:

$ var="Hello"
$ echo '$var'
$var
$ echo "$var"
Hello
Run Code Online (Sandbox Code Playgroud)

如上所示,shell按字面意思处理单引号的内容.它不会改变单引号内的内容.相比之下,shell将处理双引号的内容,执行变量替换(如上所示),以及命令替换和算术扩展.为了证明后两者:

$ echo '$var $(date) $((2*3))'
$var $(date) $((2*3))
$ echo "$var $(date) $((2*3))"
Hello Wed Nov 19 14:15:44 PST 2014 6
Run Code Online (Sandbox Code Playgroud)