Mengapa saya tidak bisa menggunakan! (Pola tunggal) di zsh bahkan setelah saya mengaktifkan kshglob?

8

Ini bekerja di bash:

touch a b c
echo !(a)

Jika saya menjalankan skrip di atas dalam zsh (dengan kshglobon), komplain:

zsh: number expected

Jika saya tambahkan |setelah a, itu berfungsi:

echo !(a|)

Mengapa?

dedowsdi
sumber

Jawaban:

10

Karena dalam kasus ini, itu bertentangan dengan kualifikasi bola kosong karena sudah di akhir pola. *(a1)diambil sebagai file yang terakhir diakses di hari terakhir. (a1)diperlakukan sebagai kualifikasi glob. Jadi dalam !(a)kasus Anda , zsh mengeluh tentang jumlah hari yang hilang setelah akualifikasi glob (di sini berlaku untuk file yang dipanggil !).

Dalam zshgumpalan, (...)pengelompokan sebagian besar digunakan untuk (foo|bar)pergantian, jadi menambahkan a |adalah cara yang terdokumentasi untuk memastikan trailing (...)tidak diperlakukan sebagai kualifikasi glob.

Alternatif lain yang didokumentasikan adalah menggandakan kurung ( !((a))) atau Anda dapat menambahkan kualifikasi glob kosong (seperti !(a)(-)).

Untuk sepenuhnya menghilangkan ambiguitas itu, seseorang dapat mematikan bare_glob_qualopsi ( set +o bareglobqual), setelah itu kualifikasi glob harus ditulis dengan extendedglob (#q...)sintaks (di *(#qa1)sini).

The kshglobpilihan ( menambahkan pada tahun 1998 , sekitar waktu yang sama bashmenambahkan-nya extglobpesta meskipun tidak memiliki gumpal diperpanjang sebelum itu) sebagian besar ada untuk kshmodus emulasi ( emulate ksh), untuk zshdapat menjalankan kshscript, di mana kshglobdiaktifkan dan bareglobqualdinonaktifkan. Ketika pertama kali diperkenalkan, setelah diaktifkan kshglob, Anda harus menentukan kualifikasi glob -(...)untuk menghindari konflik semacam itu tetapi itu menyebabkan terlalu banyak kebingungan dan bertentangan dengan @-(...)sintaksis ksh93, opsi (#q...)dan bareglobqualdiperkenalkan kemudian.

zshpengguna umumnya lebih suka set -o extendedgloboperator extended glob ( ) milik zsh yang lebih mudah mengetik (untuk sebagian besar) dan lebih kuat (daripada yang diaktifkan dengan ksh88 kshglobjuga ditemukan di bash -O extglob).

Misalnya !(foo)akan ditulis ^foo. Namun yang !(foo|)barsetara akan lebih lama seperti (^(foo|))bar.

Other ksh88 -> terjemahan zsh:

  • *(x) -> x#
  • +(x) -> x##
  • @(x|y) -> x|y
  • ?(x) -> (x|)

Beberapa terjemahan ksh93 -> zsh:

  • ~(i:x)-> (#i)x(case-sensitive)
  • ~(N)x-> x(N)(nullglob, berasal dari zsh)
  • {1,5}(x) -> x(#c1,5)
  • @(foo&bar)-> foo~^baratau^(^foo|^bar)

Beberapa hanya ditemukan di zsh:

  • <1-23> (rentang angka desimal)
  • pattern~except
  • pattern(glob-qualifier) (fitur pembunuh dari gumpalan zsh)
  • (pattern/)#(setiap tingkat subdirektori yang cocok dengan pattern; **/versi disederhanakan (*/)#juga ditambahkan ke ksh93 dan bash baru-baru ini)
  • ***/* (globung rekursif berikut symlinks).
  • (#a1)foobar (perkiraan pencocokan, memungkinkan beberapa kesalahan, di sini 1)
  • ...
Stéphane Chazelas
sumber