Saya memiliki string yang merupakan hasil dari beberapa operasi yang tidak dapat saya kendalikan. Ketika saya mencetak variabel ini menggunakan echo
, saya mendapatkan:
echo $myvar
hello
Namun, ketika saya melakukannya
if [ $myvar = "hello" ]; then
echo they are equal
else
echo they are not equal
fi
Saya selalu mendapatkan bahwa mereka tidak setara. Saya menduga ini karena newline
karakter.
Tali juga bertingkah aneh. Ketika saya melakukannya:
newVAR="this is my var twice: "$myvar$myvar
echo $newVAR
Saya mendapat:
hellois my var twice: hello
Bagaimana saya bisa memeriksa apakah ini disebabkan oleh newline
dan, jika demikian, hapus?
printf '%q\n' "$string"
mendapatkan versi apa pun dari string apa pun. Misalnya:printf '%q\n' 'foo\n'
->foo\\n
;printf '%q\n' $'foo\n'
->$'foo\n'
echo $foo
. Lakukanecho "$foo"
sebaliknya.Jawaban:
Masalahnya adalah Anda memiliki Carriage-Return (CR,
\r
) yang tertanam . Hal ini menyebabkan titik penyisipan teks terminal untuk menendang kembali ke awal baris yang sedang dicetak. Itulah sebabnya Anda melihat 'halo' di awal baris dalam$newVAR
contoh Anda -sed -n l
menampilkan tampilan yang dapat dibaca dari karakter yang tidak diinginkan (dan akhir baris).Anda dapat mengujinya dengan cek kondisi bash sederhana:
Anda dapat menggabungkan pengujian dan memperbaikinya dalam satu langkah dengan menguji untuk
\r
dan menghapusnya melalui:Cara mengatasinya menggunakan Shell Parameter Expansion . Bentuk khusus yang digunakan di atas adalah untuk mengganti substring berdasarkan pola yang Anda buat:
${parameter/pattern/string}
<- Ini hanya menggantikan pola yang ditemukan pertama kali dengan string dalam variabel bernama * parameter. Untuk mengganti semua pola, Anda hanya perlu mengubah yang pertama/
untuk//
.sumber
fix="....
garis?fix
dapat denganvar
sendirinya - atau seringkali Anda hanya dapat menggunakan ekspansi parameter apa adanya tanpa perlu menetapkan ulang nilai (mungkin) yang dimodifikasi ..Anda dapat mewakili
\r
seperti$'\r'
dalam bash:Atau potong yang terakhir
\r
dimyvar
:sumber
Anehnya, dalam banyak cangkang
getopts
adalah kandidat yang sangat mungkin untuk pekerjaan seperti ini. Ini mungkin tampak berlawanan dengan intuisi pada awalnya, tetapi jika Anda menganggap bahwagetopts
'fungsi utama adalah untuk mengenali dan menawarkan untuk penafsiran sebanyak opsi opsi baris perintah karakter tunggal yang ditentukan seperti yang dapat ditemukan dalam serangkaian yang sama, mungkin mulai membuat sedikit lebih masuk akal.Untuk menunjukkan, dari
bash
shell:Dengan cara itu kadang-kadang bisa lebih mudah untuk memungkinkan
getopts
menangani pembongkaran sebagai semacam pilot otomatis shell untuk kasus-kasus seperti ini. Ketika Anda melakukannya, Anda bisa menyaring byte yang tidak diinginkan dengancase
atau[
menguji]
dan membangun kembali string Anda dari byte 1:Dengan contoh kasus sederhana ini - dan diberi shell yang mendukung ekspansi parameter yang telah disebutkan di tempat lain - mengatakan ekspansi mungkin akan melayani Anda lebih baik di sini. Tapi saya pikir
getopts
mungkin layak disebut juga jika Anda tidak menyadari kemampuannya dalam hal ini. Tentu saja ketika saya mengetahuinya, saya menemukan banyak aplikasi yang berguna untuk itu.sumber
Meskipun Bash dan bahasa shell lainnya berguna, terkadang lebih baik menggunakan bahasa skrip yang sebenarnya - seperti Perl. Perl dapat mengganti skrip shell yang memanggil bahasa lain seperti sed dan awk serta perintah UNIX dengan mudah. Saya belajar ini 20+ tahun yang lalu ketika menulis skrip C-Shell yang pada gilirannya disebut sed, awk, dan berbagai perintah UNIX - sebelum memanggil kode FORTRAN. Dalam Perl saya akan melakukan:
sumber