Meloloskan kutipan dalam alias zsh

12

Sebagai lanjutan dari pertanyaan ini tentang menghapus baris baru dari teks, saya ingin mengubahnya menjadi alias zsh sebagai berikut:

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

Saya telah mencoba melarikan diri dari kutipan di dalam skrip awk, tetapi saya mendapatkan kesalahan ini:

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

(File ini disebut bspsrobustness)

Apakah ada cara untuk melakukan apa yang saya inginkan? Saya kira saya bisa mengubah ini menjadi skrip awk daripada zsh alias, apakah itu pilihan terbaik saya?

Seamus
sumber
Omong-omong, ini berlaku untuk semua shell (gaya Bourne, bukan csh).
Gilles 'SANGAT berhenti menjadi jahat'

Jawaban:

9

Anda bisa menggunakan fungsi zsh sebagai ganti alias. Tidak ada lingkaran kutipan untuk dilewati.

striplines() {
    awk '... awk body "with quotes" ...' "$@"
}
glenn jackman
sumber
Lalu bagaimana saya menyebutnya : striplines filename?
Seamus
dapatkah Anda menjelaskan apa yang "$@"dilakukannya?
Seamus
@ Seamus, ya Anda akan menyebutnya persis seperti itu. The "$@"sintaks mengirimkan striplines argumen untuk awk terganggu - diperlukan jika, katakanlah, setiap nama file Anda berisi spasi: striplines "file 1" "file 2"akan mengirimkan dua nama file ke awk.
glenn jackman
5

Untuk mengetahui apa yang sedang terjadi, jalankan

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

Karena $karakter dalam tanda kutip ganda (ketika mereka diperluas setelah alias diperluas), mereka ditafsirkan oleh shell. Untuk mendapatkan kutipan yang benar, lebih mudah untuk menempatkan seluruh definisi alias dalam tanda kutip tunggal. Apa yang ada di dalam tanda kutip tunggal adalah apa yang akan diperluas ketika alias digunakan. Sekarang argumen awkdikelilingi dalam tanda kutip ganda, jelas bahwa Anda perlu backslash sebelumnya \"$.

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

Sebuah idiom yang berguna untuk mengutip tunggal string yang dikutip tunggal adalah cara yang '\''cukup banyak untuk menempatkan kutipan tunggal literal dalam string yang dikutip tunggal. Secara teknis ada penjajaran string dengan tanda kutip tunggal, tanda garis miring terbalik ', dan string tanda kutip tunggal. String kosong disandingkan ''di akhir dapat dihapus.

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

Setelah penjelasan panjang ini, sebuah rekomendasi: ketika terlalu rumit untuk sebuah alias, gunakan sebuah fungsi .

Gilles 'SANGAT berhenti menjadi jahat'
sumber