Jika, jika tidak sengaja, Anda hanya mencoba menangani tanda kutip untuk menggunakan kembali shell, maka Anda dapat melakukan ini tanpa menghapusnya, dan itu juga sederhana:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
Shell fungsi itu mengutip setiap argumen arg yang Anda berikan dan meningkatkan outputnya per argumen yang dapat diperbaiki.
Ini dia dengan beberapa argumen:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
KELUARAN
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
Keluaran itu dari dash
mana biasanya kutipan dengan kutip tunggal berupa keluaran yang disukai '"'"'
.bash
akan lakukan '\''
.
Mengganti pilihan byte tunggal, non-spasi putih, non-nol dengan byte tunggal lainnya mungkin dapat dilakukan paling cepat di setiap shell POSIX dengan $IFS
dan $*
.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
KELUARAN
"some ""crazy """"""""string ""here
Di sana saya hanya printf
agar Anda dapat melihatnya, tetapi tentu saja, jika saya telah melakukannya:
var="$*"
... daripada printf
perintah$var
akan menjadi apa yang Anda lihat di output di sana.
Ketika saya set -f
memerintahkan shell untuk tidak glob - jika string berisi karakter yang dapat ditafsirkan sebagai pola glob. Saya melakukan ini karena parser shell memperluas pola glob setelah melakukan pemisahan bidang pada variabel. globbing dapat diaktifkan kembali seperti set +f
. Secara umum - dalam skrip - saya merasa berguna untuk mengatur bang saya seperti:
#!/usr/bin/sh -f
Dan kemudian secara eksplisit mengaktifkan globbing dengan set +f
apa pun garis yang saya inginkan.
Pemecahan bidang terjadi berdasarkan karakter dalam $IFS
.
Ada dua jenis $IFS
nilai - $IFS
spasi putih dan $IFS
non-spasi putih. bidang terbatas $IFS
spasi (spasi, tab, baris baru) ditetapkan untuk dihapus oleh urutan ke satu bidang (atau tidak sama sekali jika tidak mendahului hal lain) - jadi ...
IFS=\ ; var=' '; printf '<%s>' $var
<>
Tetapi semua yang lain ditentukan untuk mengevaluasi ke satu bidang per kejadian - mereka tidak terpotong.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
Semua ekspansi variabel, secara default, $IFS
array data dibatasi - mereka dibagi ke bidang yang terpisah sesuai dengan $IFS
. Ketika Anda "
-quote satu Anda menimpa properti array itu dan mengevaluasinya sebagai string tunggal.
Jadi ketika saya melakukannya ...
IFS=\"\'\`; set -- $var
Saya mengatur array argumen shell ke banyak $IFS
bidang terbatas yang dihasilkan oleh $var
ekspansi. Ketika diperluas nilai konstituen untuk karakter yang terkandung dalam $IFS
yang hilang - mereka hanya pemisah lapangan sekarang - mereka \0NUL
.
"$*"
- seperti ekspansi variabel ganda yang dikutip ganda - juga mengesampingkan kualitas pemisahan bidang dari $IFS
. Tetapi, di samping itu , ia menggantikan byte pertama $IFS
untuk setiap bidang yang dibatasi di "$@"
. Jadi karena "
merupakan pertama nilai dalam $IFS
semua pembatas berikutnya menjadi "
di "$*"
. Dan yang "
tidak perlu ada di $IFS
saat Anda membaginya, juga. Anda bisa mengubah $IFS
setelah set -- $args
ke nilai lain seluruhnya dan byte pertama yang baru kemudian akan muncul untuk pembatas bidang di "$*"
. Terlebih lagi, Anda dapat menghapus semua jejak mereka sepenuhnya seperti:
set -- $var; IFS=; printf %s "$*"
KELUARAN
some crazy string here
tr
. BASH's PE bagus tetapi tr jauh lebih cepat dalam kasus ini. mis.echo "$OUTPUT" | tr -dc '[[:alpha:]]'
karena Anda hanya ingin memiliki alfanumerik