Wednesday, October 31, 2012

Masalah menggunakan Perl sebaris dlm Windows

Penggunaan Perl sebaris (one-liner) dalam Windows amnya tidaklah rumit atau bermasalah. Tetapi ada masanya masalah tertentu akan timbul disebabkan peraturan-peraturan tertentu dalam prom arahan (command-prompt) Windows.

Contohnya, baru-baru ini saya terjumpa satu kaedah yang mencadangkan penggunaan pemboleh ubah persekitaran (environment variable) dalam Perl sebaris. Bagusnya kaedah ini ialah jika Perl sebaris kita terlalu panjang (untuk kod satu baris) tetapi kerap digunakan, kita boleh mengurangkan kerja menaip (andaikan kita tidak mahu guna fail batch). Contohnya bagi Perl sebaris berikut,
perl -ne  "print if /^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)([eE][+-]?[0-9]+)?$/" file.txt
bukan saja hendak menulis, bahkan hendak menghafalnya pun sudah rumit. Maka kita boleh gunakan pemboleh ubah persekitaran. Arahan berikut membentuk satu pemboleh ubah baru bernama format_nombor :
set format_nombor="^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)([eE][+-]?[0-9]+)?$"
(dwi-quot diperlukan kerana jika tidak ada, arahan SET tidak berjaya. Tapi masalah lain pula timbul, dan dibincangkan di bawah) Jadi sepatutnya saya boleh gunakan interpolasi nilai pemboleh ubah ke dalam arahan Perl sebaris seperti berikut, sekaligus memudahkan penulisan arahan Perl sebaris,
perl -ne  "print if /%format_nombor%/" file.txt
Malangnya ini tidak berjaya kerana Windows merungut dengan mesej berikut,
'[.][0-9]+)' is not recognized as an internal or external command, operable program or batch file.
Apa masalahnya? Masalahnya ialah hasil interpolasi tidak seperti yang dijangka! Lihat hasil di bawah ini:
perl -ne  "print if /"^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)([eE][+-]?[0-9]+)?$"/" file.txt
Perhatikan sepasang dwi-quot yang terhasil dalam dwi-quot. Jadi Perl sebaris yang terhasil tidak sah! 

Masalah ini sebenarnya berpunca daripada nilai dalam %format_nombor% yang sudahpun mempunyai dwi-quot (boleh dilihat dengan arahan SET %format_nombor%). Maka bila diinterpolasi, dwi-quot itu akan turut serta sebagai sebahagian nilai pemboleh ubah. 

Untuk menyelesaikan masalah ini, dwi-quot itu perlu dibuang daripada nilai %format_nombor%. Hal ini mulanya memeningkan kerana dalam arahan SET dwi-quot itu diperlukan. Setelah puas mencari, rupa-rupanya arahan SET dengan dwi-quot itu boleh ditulis dengan cara lain. Caranya ialah seperti di bawah ini (kedudukan dwi-quot bermula sebelum nama pemboleh ubah, dan bukan setakat merangkumi nilai),
set "format_nombor=^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)([eE][+-]?[0-9]+)?$"
Selepas menggunakan cara ini, dwi-quot sudah tidak ada dalam nilai %format_nombor% (boleh dipaparkan menggunakan arahan SET %format_nombor%). Maka apabila diinterpolasi sudah tidak ada masalah.
perl -ne  "print if /%format_nombor%/" file.txt
Maka setelah berjaya menemui kaedah ini, penggunaan Perl sebaris yang agak panjang dapat dipermudahkan.

Habis cerita.


Notakaki
  1. Kod Perl sebaris itu sebenarnya berfungsi mencari nombor-nombor yang sah (mengikut standard IEEE) dalam setiap baris fail input (fail.txt). Setiap nombor yang sah akan dipaparkan. Nombor hanya dikesan jika terdapat satu nombor dalam setiap baris.
  2. Untuk membuang pemboleh ubah yang kita isytiharkan, gunakan arahan SET tanpa nilai, seperti berikut,
  3. set format_nombor=
  4. Selain kaedah di atas, pemboleh ubah persekitaran bagi Windows sebenarnya boleh dibentuk/disunting melalui antaramuka GUI (klik kanan pada ikon My Computer->Properties. Cari tab Environment variables dan tambah pemboleh ubah dengan nilai yang diperlukan)

No comments:

Post a Comment