awk 的 $ 与 shell 的 $ 有何不同?

Pra*_*r-M -1 shell awk

在 awk 中,我们$用来提取由IFS

awk `/LIG/{print $1, $2}' topol.top
Run Code Online (Sandbox Code Playgroud)

在 shell 中,我们$用于提取我们为变量存储的值。例如。for环形。

for i in *; do
    mv -- $i $i.pdb; done 
Run Code Online (Sandbox Code Playgroud)

(根据答案更正)

$在这两个背景下本质上是相同的或不同的使用情况如何?

如果不同,为什么会不同?如何将awk和shell$混在一起使用?

Ed *_*ton 7

$在 shell 和$awk 中只是看起来它们是相关的,因为有时$在 shell之后可以有一个数字,有时在后面有一个变量,在 awk 中也是如此,但它们没有任何关系,只是 2 使用的相同字符在 2 个完全不同的上下文中完全不同的工具,shell 中的内容$<number>$<variable>含义与它们在 awk 中的含义完全不同。

在 shell 中,您可以通过添加变量来取消引用变量,$并且位置参数等在这方面被视为与变量相同,因此您可以拥有:

$0 = the path to the current command
$1 = the first argument passed to the command
$2 = the second argument passed to the command
$# = the number of arguments passed to the command
$? = the exit status of the last command run
$var = the value of the shell variable var
etc.
Run Code Online (Sandbox Code Playgroud)

在 awk 中$是当前记录拆分成的字段数组(概念上)的名称,因此您只能$在这些表达式中使用:

$0 = the current record being processed
$1 = the first field of the current record
$2 = the second field of the current record
Run Code Online (Sandbox Code Playgroud)

要取消引用 awk 变量var,您只需使用它的 name var,就像在 C 中一样,实际上 awk 语法与 C 的相似度远高于与 shell 的相似度。

如果您曾经$var在 awk 中看到使用过,那么它不是$解引用var,而是var单独使用名称进行解引用var,如果var有一个数值,例如 say, 5,则$var表示与$5当前记录的第 5 个字段相同,如果var是没有数值则$var意味着与$0当前记录相同:

var=0 => $var = $0 = the current record being processed
var=1 => $var = $1 = the first field of the current record
var=2 => $var = $2 = the second field of the current record
var="" => $var = $0 = the current record being processed
var="foo" => $var = $0 = the current record being processed
Run Code Online (Sandbox Code Playgroud)

awk 和 shell 是 2 个完全不同的工具,它们有自己的语法、语义和变量范围等。所以就这样对待它们,不要假设你在 awk 脚本中看到的任何东西与你在 a语法、语义或范围内的 shell 脚本,反之亦然。

  • 在`print $ "2"`的情况下,它看起来更像是gawk解析`print`语句的错误。`print($ "2")` 或 `a = $ "2"` 看起来不错,但 `print $ "2"` 的行为就像 `print $0`。`$ 1.2` 仅在我的测试中是 `mawk` 的问题,并且仅对于文字值,`a = 1.2; 打印 $ a` 很好。 (3认同)
  • 我发现澄清 `awk` 中的 `$` 更像是一元运算符 `-` 或 `!` 很有用。`- &lt;expression&gt;` 将 `&lt;expression&gt;` 转换为一个数字并给出相反的数字,`$ &lt;expression&gt;` 将 `&lt;expression&gt;` 转换为一个整数并给出相应的字段(或完整记录,如果该值是 0)。`$ (1 + 1)` 为您提供第二个字段。`$(1 - 1)` 完整记录。当 `&lt;expression&gt;` 首先不是整数时,实现之间会有一些变化,例如 `$ "2"`(使用 `$ (0 + "2")` 以实现可移植性或 `$ 1.2`(使用`$ int(1.2)` 可移植性)。 (2认同)
  • @StéphaneChazelas 起初我认为这可以通过字段引用比除分组以外的所有其他操作更高的优先级来解释,但是因为`print $("2")`、`print ($"2")`、`printf "%s\n ", $"2"`, 和 `a=$"2"; 打印 a` all 输出 `$2` 的值,我已经放弃了这个理论并同意,这看起来像一个错误。我给那些呆呆的家伙发了一封电子邮件,要么把它作为错误报告提交,要么得到一个解释。见 https://lists.gnu.org/archive/html/bug-gawk/2020-06/msg00022.html (2认同)