在 zsh 别名中转义引号

在 zsh 别名中转义引号

继从这个问题关于从文本中删除换行符,我想将其转换为 zsh 别名,如下所示:

alias striplines=' awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'

我尝试转义 awk 脚本中的引号,但收到此错误:

awk: (FILENAME=bspsrobustness FNR=1) fatal: division by zero attempted

(该文件名为bspsrobustness

有办法做我想做的事吗?我想我可以把它变成 awk 脚本而不是 zsh 别名,这是我最好的选择吗?

答案1

您可以使用 zsh 函数而不是别名。无需跳过引用的圈子。

striplines() {
    awk '... awk body "with quotes" ...' "$@"
}

答案2

要了解发生了什么,请运行

% alias striplines='print -lr awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'
% striplines
awk
 /^$/ {print "\n"; } /./ {printf( " %s ",zsh);}

由于$字符位于双引号中(当它们在别名展开后展开时),因此它们由 shell 解释。为了获得正确的引用,将整个别名定义放在单引号中会更容易。单引号内的内容是使用别名时将扩展的内容。现在 的参数awk被双引号括起来,很明显在 之前需要反斜杠\"$

alias striplines='print -lr awk " /^\$/ {print \"\n\"; } /./ {printf( \" %s \",\$0);}"'

对单引号字符串进行单引号的一个有用的习惯用法是,这'\''几乎是一种将文字单引号放入单引号字符串中的方法。从技术上讲,单引号字符串、反斜杠引号'和另一个单引号字符串并置。''末尾并列的空串可以去掉。

alias striplines='print -lr awk '\'' /^$/ {print "\n"; } /./ {printf( " %s ",$0);}'\'

经过这么长的解释,有一个建议:当别名对于别名来说太复杂时,使用函数

答案3

如果您正在使用zsh,您还可以打开rcquotes选项:

允许字符序列''表示单引号字符串中的单引号。请注意,这不适用于使用格式的带引号的字符串$'...',其中可以使用反斜杠单引号。

因此,代替

alias striplines='print -lr awk '\'' /^$/ {print "\n"; } /./ {printf( " %s ",$0);}'\'

使用rcquotes你可以写

setopt rcquotes
alias striplines='print -lr awk '' /^$/ {print "\n"; } /./ {printf( " %s ",$0);}'''

或者,通过使用$'...'你可以写

alias striplines=$'print -lr awk \' /^$/ {print "\n"; } /./ {printf( " %s ",$0);}\''

相关内容