Bash别名和awk中引号的转义

9
我正在尝试为一个命令创建别名来查看内存使用情况,
ps -u user -o rss,command | grep -v peruser | awk '{sum+=$1} END {print sum/1024}'

但是,对于技术不了解的人来说,这可能有点棘手。
#.bash_aliases
alias totalmem='ps -u user -o rss,command | grep -v peruser | awk '{sum+=$1} END {print sum/1024}''

会产生错误:

-bash: alias: END: not found
-bash: alias: {print: not found
-bash: alias: sum/1024}: not found

我已经尝试过使用双引号,totalmem ="ps ... |awk '{sum+=$1} END {print sum/1024}'", 或者使用转义符,totalmem ='ps ... |awk "{sum+=$1} END {print sum/1024}"',以及转义双引号... 但似乎都无法使其正常工作。而totalmem ='ps ... |awk \'{sum+=$1} END {print sum/1024}\',则会报错。使用totalmem ='ps ... |awk \"{sum+=$1} END {print sum/1024}\"'也会出现错误。
awk: "{sum+=}
awk: ^ unterminated string

非常感谢任何技巧或建议。


1
http://www.unix.com/shell-programming-scripting/38249-define-alias-embeded-awk-command.html - Can Geliş
2
永远不需要使用 grep,只需使用 awk '$0!~/peruser/{sum+=$1}END{print sum/1024}' - Chris Seymour
1
@Massagran,只要你还在这里——我想鼓励你考虑切换到建议使用函数的答案,这样可以完全避免问题。(函数比别名更强大——它们可以执行条件逻辑;它们有自己的调用堆栈条目和参数列表;它们可以导出到环境中;它们默认情况下在脚本内工作,而别名不行;等等)。#bash IRC频道关于别名的事实长期以来一直说“如果你必须问,请使用函数代替”。这些都是明智的话。 - Charles Duffy
3个回答

20

你可以使用Shell函数而不是别名来避免引用问题:

totalmem () {
  ps -u user -o rss,command | grep -v peruser | awk '{sum+=$1} END {print sum/1024}'
}

这也更加灵活,因为您可以允许totalmem接受参数,例如一个用户名,以便将其传递给ps-u选项,就像这个例子中一样:

totalmem () {
  ps -u "$1" -o rss,command | grep -v peruser | awk '{sum+=$1} END {print sum/1024}'
}

12

你已经接近成功了,$符号在双引号中会被扩展,所以需要额外进行转义:

alias totalmem='ps -u user -o rss,command | grep -v peruser | awk "{sum+=\$1} END {print sum/1024}"'

或者按照 iiSeymour 建议的,在 awk 内部使用模式:

alias totalmem='ps -u user -o rss,command | awk "!/peruser/ {sum+=\$1} END {print sum/1024}"'

4
谢谢“锤子之神”。我刚刚找到了一个解决方案,使用别名alias memuse='ps -u user -o rss,command | grep -v peruser | awk '"'"'{sum+=$1} END {print sum/1024}'"'"',但是您的方式更简洁。 - Massagran
1
@Massagran 感谢你,来自一名 macOS 用户的感谢。你刚刚拯救了我的一天。 - Randy Lam

9

像这样:

alias totalmem='ps -u user -o rss,command | grep -v peruser | awk '\''{sum+=$1} END {print sum/1024}'\'

解释:你可以为同一参数使用不同类型的引号,如:"我是双引号" '我没有$HOME' -i-am-not-quoted'。因此,如果你需要单引号内嵌单引号,你可以添加'\''来(1)终止单引号,(2)添加字面单引号\',(3)重新开始单引号。

(这种大小的别名最好做成函数形式。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接