Saya mencoba melakukan operasi matematika dengan sed
, tetapi terus memperlakukan variabel saya sebagai string. Masukan dari jenis ini:
$ echo 12 | sed 's/[0-9]*/&+3/'
$ 12+3
Saya ingin memiliki 15 sebagai output. Saya perlu melakukan operasi dan mengganti hasil matematika hanya dalam satu bagian, karena saya menjalankan program sebagai daemon Python, dan saya ingin menghindari bagian seperti mengarahkan ulang stdout
pada file, membuka file-file itu, melakukan operasi, mengekstrak hasilnya, lakukan penggantian. Bagi saya, sed
sepertinya yang terbaik untuk melakukan semuanya dalam satu baris.
Saya sudah mencoba melakukan input dan output dengan berbagai cara seperti
$ echo 12 | sed 's/[0-9]*/int(&+3)/'
$ echo 12 | sed 's/[0-9]*/\int(&+3)/'
$ echo 12 | sed 's/[0-9]*/\int(&+3)/'
tetapi hasilnya selalu berupa cetakan bidang kedua.
sed
matematikaJawaban:
Jika Anda benar-benar ingin menggunakan sed, maka inilah caranya:
Memasukkan:
Keluaran:
Misi Anda, jika Anda memilih untuk menerimanya, adalah menerapkan perkalian.
sumber
sed
bukan pilihan terbaik di sini, itu tidak melakukan aritmatika secara asli (lihat Menambah nomor untuk bagaimana Anda bisa melakukannya). Anda dapat melakukannya denganawk
:Sepotong kode terbaik untuk digunakan akan tergantung pada format yang tepat dari input Anda dan apa yang ingin / perlu Anda lakukan jika itu bukan angka, atau mengandung lebih dari satu angka, dll.
Anda juga dapat melakukan ini hanya dengan
bash
:atau menggunakan
expr
cara yang serupa.sumber
Saya mencoba menerima tantangan Anda @Richter, inilah yang saya lakukan menggunakan bagian dari kode Anda:
Memasukkan:
Output: semua hasil yang benar
sumber
perl
memungkinkan untuk konstruksi yang sangat mirip dengansed
... satu perbedaan adalah bahwaperl
dapat melakukan hal - hal yang lebih kompleks ...sed
sangat baik untuk subtitle teks sederhanakeluaran
sumber
perl -pe 's/[0-9]+/$&+3/e'
masukkan saja string ke dalam kalkulator
sumber
Saya benar-benar tidak mengerti mengapa kompleksitas ekstrim dari jawaban yang diterima, salah satu di bawah ini melakukan apa yang Anda inginkan:
atau
Saya pikir itu mungkin memerlukan sed GNU, tapi saya tidak yakin.
sumber
echo 12+3 | sed -r 's/([0-9]*) *\+ *([0-9]*)/expr \1 + \2/e'
Jika Anda benar-benar harus menggabungkan ekspresi reguler dan operasi aritmatika, pilih bahasa di mana parameter penggantian ekspresi reguler dapat menjadi fungsi callback.
Perl, Ruby, JavaScript, dan Python adalah bahasa-bahasa tersebut:
sumber
bash
Solusi sederhana lain , yang benar-benar berfungsi di pipa:sumber
Jika Anda mencampur beberapa bashism:
Untuk mengekstrak nomor dari teks:
Tanpa sed, cukup bash:
menggantikan setiap non-digit
${var//[^0-9]/}
dan melakukan aritmatika dalam parens putaran ganda:$((x+3))
sumber
$((...))
diperkenalkan oleh POSIX (bashismenya$[...]
).${var//xxx/x}
adalah kshism juga disalin oleh zsh dan bash.sed -r
adalah GNUismInilah solusi Perl:
Jika Anda lebih suka mengubah set digit pertama yang ditemukan dalam sebuah string, Anda dapat menggunakan:
Jika Anda lebih suka mengubah semua set digit dalam sebuah string, Anda dapat menggunakan
/g
pengubah, seperti ini:sumber
Meskipun menggunakan ekspresi sed itu bagus itu memiliki keterbatasan. Misalnya gagal berikut:
Untuk mengatasi keterbatasan ini, saya cukup beralih ke kekuatan bawaan sed murni dan mengimplementasikan berikut ini:
Cara kerjanya adalah dengan menerapkan modul penambah desimal yang menambahkan dua digit input (A dan B) serta Carry Bit dan menghasilkan Sum dan Carry bit. Idenya dipinjam dari elektronik di mana biner adder melakukan hal yang sama untuk nomor biner. Yang harus kita lakukan adalah melingkari penambah di atas semua angka dan kita dapat menambahkan angka panjang acak (dibatasi oleh memori). Di bawah ini adalah penambah yang sedang beraksi:
Dengan cara yang persis sama seseorang dapat mengimplementasikan adder biner (atau basis lainnya). Yang harus Anda lakukan adalah mengganti garis yang dimulai dengan
s/$/;000=00001...
pola substitusi yang tepat untuk basis yang diberikan. Sebagai contoh:s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/
adalah pola substitusi untuk penambah panjang biner sewenang-wenang.Anda dapat memasukkan kode yang didokumentasikan di github saya .
sumber