, Kapalı-şans, sadece yeniden iyon kabuk için tırnak işlemek çalışıyorsanız, o zaman bunu yapabilirsiniz olmadan bunları kaldırmayı, hem bu da ölü basit:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
Bu işlev kabuğu, elinizdeki herhangi bir arg dizisini tırnak içine alır ve çıktısını yinelenebilir argüman başına artırır.
İşte birkaç argüman ile:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
ÇIKTI
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
Bu çıktı dash
genellikle tek tırnaklı çıktıyı güvenli şekilde tırnak içine alır '"'"'
. bash
olur '\''
.
Tek, boşluk olmayan, boş olmayan bir bayt seçimini başka bir tek baytla değiştirmek, $IFS
ve ile herhangi bir POSIX kabuğunda en hızlı şekilde yapılabilir $*
.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
ÇIKTI
"some ""crazy """"""""string ""here
Orada sadece printf
bunu görebiliyorsunuz, ama tabii ki, eğer yapmışsam:
var="$*"
... printf
komutun $var
değeri yerine oradaki çıktıda gördüğünüz değer olacaktır.
Ben ne zaman set -f
ben kabuk talimat değil glob - durumda dize glob desen addedilecek bir karakter içeriyor. Bunu ben çünkü kabukları ayrıştırıcı değişkenler üzerinde alan bölme gerçekleştirdikten sonra glob kalıpları genişletir . globbing gibi yeniden etkinleştirilebilir set +f
. Genel olarak - komut dosyalarında - Patlamamı ayarlamak için yararlı buluyorum:
#!/usr/bin/sh -f
Ve daha sonra açıkça globbing etkinleştirmek ile set +f
bunu isteyebilirsiniz hat ne olursa olsun.
Alan ayırma işlemi, $IFS
.
İki tür $IFS
değer vardır - $IFS
boşluk ve boşluk $IFS
olmayan. $IFS
boşluk (boşluk, sekme, satırsonu) ayrılmış alanlar tek bir alana sırayla elide olarak belirtilir (veya başka bir şeyden önce yoksa hiçbiri) - yani ...
IFS=\ ; var=' '; printf '<%s>' $var
<>
Ancak diğer tüm oluşumlar için tek bir alanı değerlendirmek üzere belirtilir - kesilmezler.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
Tüm değişken genişletmeler varsayılan olarak $IFS
sınırlandırılmış veri dizileridir - alanlara göre ayrılırlar $IFS
. Bir "
alıntı yaptığınızda, o dizi özelliğini geçersiz kılar ve tek bir dize olarak değerlendirirsiniz.
Öyleyse yaptığım zaman ...
IFS=\"\'\`; set -- $var
Kabuğun argüman dizisini 's genişleme $IFS
tarafından oluşturulan birçok ayrılmış alanlara ayarlıyorum $var
. O karakterler için kendisini oluşturan değerleri genişletildiğinde içerdiği $IFS
edilir kaybetti - artık sadece saha ayırıcılardır - bunlar \0NUL
.
"$*"
- diğer çift tırnaklı değişken açılımları gibi, alan ayırma özelliklerini de geçersiz kılar $IFS
. Fakat ek olarak , bu ilk bayt yerine $IFS
her sınırlandırılmış alan için de "$@"
. Yani çünkü "
oldu ilk değer $IFS
sonraki tüm sınırlayıcı haline "
de "$*"
. Ve "
gerek yok$IFS
bölündüğünüzde de . $IFS
Sonra set -- $args
başka bir değere tamamen geçebilirsiniz ve yeni ilk baytı alan sınırlayıcıları için görünecektir "$*"
. Dahası, tüm izlerini tamamen şöyle kaldırabilirsiniz:
set -- $var; IFS=; printf %s "$*"
ÇIKTI
some crazy string here
tr
. BASH'in PE'si iyidir, ancak bu durumda tr çok daha hızlıdır. örneğinecho "$OUTPUT" | tr -dc '[[:alpha:]]'
sadece alfasayısal kullanmak istediğiniz için