英文:
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]++'
在第一种形式中,由于它在单引号内部,变量没有被替换。
本回答讨论了在bash
和zsh
中单引号和双引号字符串的处理方式:
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]++'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论