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 dashmana biasanya kutipan dengan kutip tunggal berupa keluaran yang disukai '"'"'.bashakan lakukan '\''.
Mengganti pilihan byte tunggal, non-spasi putih, non-nol dengan byte tunggal lainnya mungkin dapat dilakukan paling cepat di setiap shell POSIX dengan $IFSdan $*.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
KELUARAN
"some ""crazy """"""""string ""here
Di sana saya hanya printfagar Anda dapat melihatnya, tetapi tentu saja, jika saya telah melakukannya:
var="$*"
... daripada printfperintah$var akan menjadi apa yang Anda lihat di output di sana.
Ketika saya set -fmemerintahkan 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 +fapa pun garis yang saya inginkan.
Pemecahan bidang terjadi berdasarkan karakter dalam $IFS.
Ada dua jenis $IFSnilai - $IFSspasi putih dan $IFSnon-spasi putih. bidang terbatas $IFSspasi (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, $IFSarray 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 $IFSbidang terbatas yang dihasilkan oleh $varekspansi. Ketika diperluas nilai konstituen untuk karakter yang terkandung dalam $IFSyang 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 $IFSsaat 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