Bash: cara mendapatkan angka pertama yang terjadi dalam konten variabel

8

cara mendapatkan jumlah variabel pertama

Saya punya variabel:

STR="My horse weighs 3000 kg but the car weighs more"
STR="Maruska found 000011 mushrooms but only 001 was not with meat"
STR="Yesterday I almost won the lottery 0000020 CZK but in the end it was only 05 CZK"

Saya perlu mendapatkan nomornya:

3000
11
20
Rui F Ribeiro
sumber

Jawaban:

7

Dengan gawk, atur pemisah rekaman RSke urutan digit. Teks yang cocok dengan RSpola dapat diambil melalui RT. Tambahkan 0untuk RTmemaksanya ke angka (sehingga menjatuhkan nol terkemuka). Keluar segera setelah instance pertama dicetak

awk -v RS=[0-9]+ '{print RT+0;exit}' <<< "$STR"

Atau di sini adalah solusi bash

shopt -s extglob
read -r Z _ <<< "${STR//[^[:digit:] ]/}"
echo ${Z##+(0)}
iruvar
sumber
Bagus. Apakah Anda peduli untuk menjelaskan?
jasonwryan
Saya tidak mengerti. Apa yang saya lakukan salah (dengan versi awk)? gist.github.com/jamiejackson/d92750cc42442a527c6b94499a13bc79
Jamie Jackson
@JamieJackson, pastikan Anda menjalankan GNU awk alias gawk
iruvar
5

Inilah salah satu cara untuk melakukannya:

echo $STR | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//'

Uji:

$ STR="My horse weighs 3000 kg but the car weighs more"
$ echo $STR | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//'
3000

$ STR="Maruska found 000011 mushrooms but only 001 was not with meat"
$ echo $STR | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//'
11

$ STR="Yesterday I almost won the lottery 0000020 CZK but in the end it was only 05 CZK"
$ echo $STR | grep -o -E '[0-9]+' | head -1 | sed -e 's/^0\+//'
20
cuonglm
sumber
Apa tujuan dari sedpada akhirnya? Sepertinya sebelum masuk ke sed kita sudah memiliki hasil yang kita inginkan.
Michael
Tidak, Anda memiliki # 2 000011yang harus Anda hapus nol leadings Tetapi Anda dapat menyederhanakan dengan mencocokkan [1-9][0-9]*yang akan menghapus nol terkemuka dari awal: echo $STR | grep -o -E '[1-9][0-9]*'
CCH
2

Jika implementasi grepAnda tidak memiliki -oatau jika Anda tidak menggunakan Bash, Anda dapat melakukan hal berikut:

printf "%.0f\n" $(printf "%s" "$string"|sed  's/^[^0-9]*//;s/[^0-9].*$//')
Joseph R.
sumber
2
#!/bin/bash

string="My horse weighs 3000 kg but the car weighs more"

if [[ $string =~ ^([a-zA-Z\ ]*)([0-9]*)(.*)$ ]]
then
    echo ${BASH_REMATCH[1]}
fi  
philippe
sumber
1
Subskrip harus 2 bukannya 1. Tapi Anda benar-benar tidak perlu kompleks regex itu. Lagipula akan gagal jika ada karakter lain di string.
Dijeda sampai pemberitahuan lebih lanjut.
2

Saya telah meletakkan string Anda dalam array sehingga dapat dengan mudah diulang untuk demonstrasi ini.

Ini menggunakan pencocokan ekspresi reguler bawaan Bash.

Hanya diperlukan pola yang sangat sederhana. Dianjurkan untuk menggunakan variabel untuk menahan pola daripada memasukkannya secara langsung dalam tes pertandingan. Ini penting untuk pola yang lebih kompleks.

str[0]="My horse weighs 3000 kg but the car weighs more"
str[1]="Maruska found 000011 mushrooms but only 001 was not with meat"
str[2]="Yesterday I almost won the lottery 0000020 CZK but in the end it was only 05 CZK"

patt='([[:digit:]]+)'

for s in "${str[@]}"; do [[ $s =~ $patt ]] && echo "[${BASH_REMATCH[1]}] - $s"; done

Saya menyertakan tanda kurung siku hanya untuk mematikan angka secara visual.

Keluaran:

[3000] - My horse weighs 3000 kg but the car weighs more
[000011] - Maruska found 000011 mushrooms but only 001 was not with meat
[0000020] - Yesterday I almost won the lottery 0000020 CZK but in the end it was only 05 CZK

Untuk mendapatkan angka tanpa nol terkemuka, cara termudah adalah dengan memaksa konversi basis-10.

echo "$(( 10#${BASH_REMATCH[1]} ))"

Mengganti itu, output tampak seperti apa yang Anda minta:

3000
11
20
Dijeda sampai pemberitahuan lebih lanjut.
sumber
1

Cari ekspresi reguler dan man grep.

echo $STR | grep -o [0-9]*

dan untuk menghapus angka nol di depan, perlakukan sebagai angka:

LIT=$(echo $STR | grep -o [0-9]*)
VAL=$(expr $LIT + 0)
echo $VAL
Sven
sumber
Solusi Anda gagal dengan variabel berisi dua angka atau angka padding nol.
cuonglm