Philipp Pavsic
Philipp Pavsic

Reputation: 11

bash: number from line into a variable


i need the Number of a specific line set into variable.
In this case: There is a line in a generated document (rsync) like this:

Number of files transferred: 23

var1=`grep -E '\<Number of files transferred: [0-9]+\>' /path/to/document.txt`<br>

gets me the line.

echo $var1 | egrep -o "[0-9]+"

shows me the 23.
I need a (good) way to get the Number in a variable.

Thanks!

Upvotes: 1

Views: 123

Answers (3)

Gareth Rees
Gareth Rees

Reputation: 65854

Three alternative approaches:

  1. You can use the ${WORD##PATTERN} parameter expansion feature in bash to extract the number:

    RSYNC=/path/to/document.txt
    TRANSFERRED=$(grep -E '^Number of files transferred: [0-9]+$' -- "$RSYNC")
    FILE_COUNT=${TRANSFERRED##*: }
    
  2. Use $IFS (the input field separator) together with the read command and a here string:

    IFS=: read _ FILE_COUNT <<<"$TRANSFERRED"
    
  3. Use sed instead of grep, as suggested by wich in another answer, but since OS X has a BSD-ish version of sed, you will need to write the command like this:

    COMMAND='s/^Number of files transferred: \([0-9]\{1,\}\)$/\1/p'
    FILE_COUNT=$(sed -n -e "$COMMAND" -- "$RSYNC")
    

But, I think an important question to ask is, why are you storing the output of rsync in a file? Do you really need to keep it? If not, then you could pipe the output of rsync into a subshell that does whatever processing you need to do. For example, you could do this kind of thing:

rsync --stats ... | {
    FILE_COUNT=unknown
    TOTAL_SIZE=unknown
    while IFS=: read KEY VALUE; do
        case "$KEY" in
            Number of files transferred) FILE_COUNT=$VALUE ;;
            Total file size) TOTAL_SIZE=$VALUE ;;
        esac
    done
    case "$FILE_COUNT" in
        1) echo "$FILE_COUNT file ($TOTAL_SIZE bytes) was transferred."
        *) echo "$FILE_COUNT files ($TOTAL_SIZE bytes) were transferred."
    esac
}

Upvotes: 0

devnull
devnull

Reputation: 123498

Use Command Substitution:

number=$(echo $var1 | egrep -o "[0-9]+")

The variable number should now have the output of the command echo $var1 | egrep -o "[0-9]+".


If your grep supports PCRE, you could say:

number=$(grep -oP '\bNumber of files transferred: \K[0-9]+\b' /path/to/document.txt)

Upvotes: 1

wich
wich

Reputation: 17127

Just select a substring if you know the length of the prefix.

var1=${var1:29}

Or, have a different approach instead of the grep

var1=$(sed -n -e '/.*\<Number of files transferred: ([0-9]\+)\>.*/\1/p' < /path/to/document.txt)

Upvotes: 0

Related Questions