web-dev-qa-db-ja.com

zshエイリアスでの引用符のエスケープ

テキストから改行を取り除くことについて この質問 に続いて、次のようにこれをzshエイリアスに変換したいと思います。

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

Awkスクリプト内で引用符をエスケープしてみましたが、次のエラーが発生します。

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

(ファイルはbspsrobustnessと呼ばれます)

私がやりたいことをする方法はありますか?これをzshエイリアスではなくawkスクリプトに変換できると思いますが、これが私の最良のオプションですか?

12
Seamus

エイリアスの代わりにzsh関数を使用できます。ジャンプする引用フープはありません。

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

何が起こっているのかを知るには、

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

$文字は二重引用符で囲まれているため(エイリアスが展開された後に展開される場合)、シェルによって解釈されます。引用を正しく行うには、エイリアス定義全体を一重引用符で囲む方が簡単です。一重引用符の中にあるのは、エイリアスが使用されたときに展開されるものです。 awkの引数が二重引用符で囲まれたので、\"$の前にバックスラッシュが必要であることは明らかです。

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

単一引用符で囲まれた文字列を単一引用符で囲むのに便利なイディオムは、'\''が、単一引用符で囲まれた文字列にリテラル単一引用符を配置するためのほとんどの方法であることです。技術的には、単一引用符で囲まれた文字列、バックスラッシュで引用された'、および別の単一引用符で囲まれた文字列の並列があります。最後に並置された空の文字列''は削除できます。

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

この長い説明の後、推奨事項:エイリアスに対して複雑すぎる場合は、 関数を使用 です。