用`$SHELL -c`运行awk命令返回不同的结果。

huangapple go评论63阅读模式
英文:

Running an awk command with $SHELL -c returns different results

问题

我试图使用awk来打印由命令返回的唯一行。为简单起见,假设命令是ls -alh

如果我在我的Z shell中运行以下命令,awk会显示ls -alh打印的所有行:

ls -alh | awk '!seen[$0]++'

然而,如果我使用$SHELL -c运行相同的命令,同时用反斜杠转义!,我只会看到输出的第一行:

$SHELL -c "ls -alh | awk '\!seen[$0]++'"

我该如何确保后一个命令打印与前一个相同的输出?

编辑1:

我最初认为!可能是问题。但是将表达式'!seen[$0]++'更改为'seen[$0]++==0'也有相同的问题。

编辑2:

看起来我应该也转义$。由于我不知道背后的原因,我不会发布答案。

英文:

I am trying to use awk to print the unique lines returned by a command. For simplicity, assume the command is ls -alh.

If I run the following command in my Z shell, awk shows all lines printed by ls -alh

ls -alh | awk '!seen[$0]++'

However, if I run the same command with $SHELL -c while escaping the ! with backslash, I only see the first line of the output printed.

$SHELL -c "ls -alh | awk '\!seen[$0]++'"

How can I ensure the latter command prints the exact same outputs as the former?

EDIT 1:

I initially thought the ! could be the issue. But changing the expression '!seen[$0]++' to 'seen[$0]++==0' has the same problem.

EDIT 2:

It looks like I should have escaped $ too. Since I do not know the reason behind it, I will not post an answer.

答案1

得分: 1

在第二种形式中,$0 在双引号字符串中被视为一个shell变量。这种替换会创建一个有趣的awk命令:

> print $SHELL -c "ls -alh | awk '\!seen[$0]++'"
/bin/zsh -c ls -alh | awk '!seen[-zsh]++'

在第一种形式中,由于它在单引号内部,变量没有被替换。

本回答讨论了在bashzsh中单引号和双引号字符串的处理方式:
https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash


转义$,使得$0 被传递给awk应该可以工作,但请注意,在被多次解析的命令中进行引用可能会变得非常棘手。

> print $SHELL -c "ls -alh | awk '\!seen[\$0]++'"
/bin/zsh -c ls -alh | awk '!seen[$0]++'
英文:

In the second form, $0 is being treated as a shell variable in the double-quoted string. The substitution creates an interestingly mangled awk command:

> print $SHELL -c "ls -alh | awk '\!seen[$0]++'"
/bin/zsh -c ls -alh | awk '!seen[-zsh]++'

The variable is not substituted in the first form since it is inside single quotes.

This answer discusses how single- and double-quoted strings are treated in bash and zsh:
https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash


Escaping the $ so that $0 is passed to awk should work, but note that quoting in commands that are parsed multiple times can get really tricky.

> print $SHELL -c "ls -alh | awk '\!seen[\$0]++'"
/bin/zsh -c ls -alh | awk '!seen[$0]++'

huangapple
  • 本文由 发表于 2023年2月10日 16:35:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75408640.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定