Bash: làm thế nào để có được số đầu tiên xảy ra trong nội dung của một biến


8

làm thế nào để có được số lượng biến đầu tiên

Tôi có một biến:

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"

Tôi cần lấy số:

3000
11
20

Câu trả lời:


7

Với gawk, đặt dấu tách bản ghi RSthành một chuỗi các chữ số. Văn bản phù hợp với RSmẫu có thể được lấy qua RT. Thêm 0vào RTđể buộc nó thành một số (do đó bỏ các số 0 đứng đầu). Thoát ngay khi bản đầu tiên được in

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

Hoặc đây là một giải pháp bash

shopt -s extglob
read -r Z _ <<< "${STR//[^[:digit:] ]/}"
echo ${Z##+(0)}

Đẹp. Bạn có quan tâm đến công phu?
jasonwryan

Tôi không hiểu Tôi đang làm gì sai (với phiên bản awk)? gist.github.com/jamiejackson/d92750cc42442a527c6b94499a13bc79
Jamie Jackson

@JamieJackson, đảm bảo bạn đang chạy GNU awk aka gawk
iruvar

5

Đây là một cách để làm điều đó:

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

Kiểm tra:

$ 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

Mục đích sedcuối cùng là gì? Có vẻ như trước khi nó đi vào sed, chúng tôi đã có kết quả như mong muốn.
Michael

Không, bạn có số 2 000011mà bạn phải loại bỏ các số 0 dẫn đầu. Nhưng bạn có thể đơn giản hóa bằng cách kết hợp [1-9][0-9]*sẽ loại bỏ các số 0 đứng đầu ngay từ đầu: echo $STR | grep -o -E '[1-9][0-9]*'
CCH

2

Nếu việc triển khai của grepbạn không có -ohoặc nếu bạn không sử dụng Bash, bạn có thể làm như sau:

printf "%.0f\n" $(printf "%s" "$string"|sed  's/^[^0-9]*//;s/[^0-9].*$//')

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  

1
Chỉ số nên là 2 thay vì 1. Nhưng bạn thực sự không cần sự phức tạp của biểu thức chính quy. Dù sao thì nó cũng sẽ thất bại nếu có các ký tự khác trong chuỗi.
Tạm dừng cho đến khi có thông báo mới.

2

Tôi đã đặt các chuỗi của bạn trong một mảng để có thể dễ dàng lặp lại cho trình diễn này.

Điều này sử dụng kết hợp biểu thức chính quy dựng sẵn của Bash.

Chỉ cần một mô hình rất đơn giản. Bạn nên sử dụng một biến để giữ mẫu thay vì kết hợp nó trực tiếp trong thử nghiệm khớp. Đó là điều cần thiết cho các mẫu phức tạp hơn.

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

Tôi chỉ bao gồm các dấu ngoặc vuông để đặt trực quan các số.

Đầu ra:

[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

Để có được các số mà không có các số 0 đứng đầu, cách dễ nhất là bắt buộc chuyển đổi cơ số 10.

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

Thay vào đó, đầu ra trông giống như những gì bạn yêu cầu:

3000
11
20

1

Tra cứu biểu thức chính quy và man grep.

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

và để loại bỏ các số 0 đứng đầu, coi nó như một số:

LIT=$(echo $STR | grep -o [0-9]*)
VAL=$(expr $LIT + 0)
echo $VAL

Giải pháp của bạn không thành công với các biến chứa hai số hoặc phần đệm số 0.
cuonglm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.