abr_stackoverflow
abr_stackoverflow

Reputation: 701

How does "read" instruction works without arguments?

I try to get dovecot mailbox size by this command doveadm -f tab quota get -u [email protected] which gives me this table:

Quota name  Type    Value   Limit   %
User quota  STORAGE 627367  104857600   0
User quota  MESSAGE 3217    -   0

I need to extract 627367 value. So I tried to use standard method:

$ doveadm -f tab quota get -u [email protected] | while read 
> do 
>     COL3=`awk '{print $3}'`
>     COL4=`awk '{print $4}'`
> done

COL3 and COL4 should give me description of value and value. I need to find out whether "COL3 == 'STORAGE'" and if yes echo COL4. Later I've noticed that while read without variable gives me data without header:

$ doveadm -f tab quota get -u [email protected] | while read 
> do 
>         cat
> done

User quota  STORAGE 627367  104857600   0
User quota  MESSAGE 3217    -   0

I found it interesting because I don't need to recognize header and I could analyze useful data. But it seemed not very easy. If I insert echo it says me that while run three times:

$ doveadm -f tab quota get -u [email protected] | while read 
> do 
>         echo "Test"
> done

Test
Test
Test

With awk while runs two times:

$ doveadm -f tab quota get -u [email protected] | while read 
> do 
>         awk '{print $3}'
> done

STORAGE
MESSAGE

But when I start to parse result I found that while runs only one time:

$ doveadm -f tab quota get -u [email protected] | while read 
> do 
>         COL3=`awk '{print $3}'`
>         echo $COL3
> done

STORAGE MESSAGE

So when I try to use

if [ "$COL3" == "STORAGE" ]
then
    echo "Test"
fi

it never works. I tried to compare with "MESSAGE" and even with "STORAGE MESSAGE". It not works.

I didn't find any information what read do without any arguments. And I want to ask, have I use standard method and parse all lines including header or I can use read without arguments and try to parse getting data? And how I can do it?

Upvotes: 2

Views: 367

Answers (2)

vdegenne
vdegenne

Reputation: 13298

as pointed by @cxw, while without parameters puts the entire line into $REPLY

So you should write

while read
do
  echo "$REPLY" | awk '/STORAGE/ { print $4 }'
done < <(doveadm -f tab quota get -u [email protected])

Upvotes: 1

cxw
cxw

Reputation: 17051

To answer your specific question,

doveadm -f tab quota get -u [email protected] | awk -- '/STORAGE/ { print $4 }'

The awk pattern /STORAGE/ selects the line that contains STORAGE, and then the print prints the number you want.

As far as read in general, see the bash-hackers wiki. read without parameters puts the entire line into $REPLY, so you shouldn't access standard input otherwise. Using awk within your read loop means that read doesn't get to see every line, because read takes lines and awk also takes lines.

Upvotes: 1

Related Questions