zshエイリアスで引用符をエスケープします。

zshエイリアスで引用符をエスケープします。

フォローするこの問題テキストから改行を削除するには、次のようにzshエイリアスに変換したいと思います。

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

awkスクリプトで引用符をエスケープしようとしましたが、次のエラーが発生しました。

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

(ファイル名はbspsrobustness

私が望むことをする方法はありますか?私はこれをzshエイリアスの代わりにawkスクリプトに置き換えることができると思います。これが最善の選択ですか?

答え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);}

文字は二重引用符で囲まれているため$(エイリアス拡張後に拡張されると)シェルで解釈されます。適切な引用を得るには、エイリアス定義全体を一重引用符で囲むのが簡単です。一重引用符内の内容は、エイリアスを使用するときに拡張される内容です。パラメータは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);}\''

関連情報