在 zsh 别名中转义引号

Sea*_*mus 16 shell zsh alias quoting

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

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

我试过在 awk 脚本中转义引号,但出现此错误:

awk: (FILENAME=bspsrobustness FNR=1) fatal: division by zero attempted
Run Code Online (Sandbox Code Playgroud)

(该文件名为bspsrobustness

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

gle*_*man 15

您可以使用 zsh 函数而不是别名。没有引用箍可以跳过。

striplines() {
    awk '... awk body "with quotes" ...' "$@"
}
Run Code Online (Sandbox Code Playgroud)


Gil*_*il' 5

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

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

由于$字符在双引号中(当它们在别名展开后展开时),它们由 shell 解释。为了正确引用,将整个别名定义放在单引号中会更容易。单引号内的内容是使用别名时将展开的内容。现在参数 ofawk用双引号括起来,很明显,您需要在\"$.

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

单引号单引号字符串的一个有用的习惯用法'\''是将文字单引号放入单引号字符串中。从技术上讲,单引号字符串、反斜杠引号'和另一个单引号字符串并置。''可以删除末尾并列的空字符串。

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

经过这么长的解释,建议:当别名太复杂时,使用函数


Ben*_*pel 5

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

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

因此,代替

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

使用rcquotes你可以写

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

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

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