, 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ı dashgenellikle tek tırnaklı çıktıyı güvenli şekilde tırnak içine alır '"'"'. basholur '\''.
Tek, boşluk olmayan, boş olmayan bir bayt seçimini başka bir tek baytla değiştirmek, $IFSve 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 printfbunu görebiliyorsunuz, ama tabii ki, eğer yapmışsam:
var="$*"
... printfkomutun $vardeğeri yerine oradaki çıktıda gördüğünüz değer olacaktır.
Ben ne zaman set -fben 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 +fbunu isteyebilirsiniz hat ne olursa olsun.
Alan ayırma işlemi, $IFS .
İki tür $IFSdeğer vardır - $IFSboşluk ve boşluk $IFSolmayan. $IFSboş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 $IFSsı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 $IFStarafı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 $IFSedilir 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