Brendan
Brendan

Reputation: 3

Conditionally matching numbers from string

I have a string of numbers formated as so:

24_1_1_1_1_1_12_1_1_13_1_1

Underscores being spaces

I need to grab 3 numbers. The first number in this case 24, then the number after the following two 1's which in this case it is a 1. Then after another two 1's would be 12. I have tried numerous sed, awk and grep solutions to get the answer but the issue is that any of the needed 3 numbers could be 1,2 or 3 digits long.

So in this example I would need the bolded numbers.

24_1_1_1_1_1_12_1_1_13_1_1

Upvotes: 0

Views: 78

Answers (4)

Scrutinizer
Scrutinizer

Reputation: 9926

Using read:

read a x x b x x c x <<< "$str"

-

$ printf "%s\n" "$a" "$b" "$c"
24
1
12

Upvotes: 0

Chris Seymour
Chris Seymour

Reputation: 85785

How about the following awk one-liner to print the first field then every field after two ones:

$ awk 'NR==1||c==2{print;c=0;next}$1==1{c++}' RS=_ file
24
1
12
13

If you want exit after a certain number of matches (e.g 3):

$ awk 'NR==1||c==2{print;c=0;m++;next}$1==1{c++}m==3{exit}' RS=_ file
24
1
12

Upvotes: 0

chepner
chepner

Reputation: 531165

Split the string into an array, then just iterate over the array:

str="24_1_1_1_1_1_12_1_1_13_1_1"
IFS="_" read -ra numbers <<< "$str"
results=( ${numbers[0]} )
take_next=0
for n in "${numbers[@]:1}"; do
    if (( take_next == 2 )); then
        results+=( $n )
        take_next=0
    elif (( n == 1 )); then
        (( take_next++ ))
    else
        take_next=0
    fi
    (( ${#results[@]} == 3 )) && break
done

Upvotes: 1

choroba
choroba

Reputation: 241858

You can set $IFS to _ and split the string into an array:

#!/bin/bash
string=24_1_1_1_1_1_12_1_1_13_1_1
OIFS=$IFS
IFS=_
ar=($string)
IFS=$OIFS
echo ${ar[0]} ${ar[3]} ${ar[6]}

Upvotes: 2

Related Questions