curiousengineer
curiousengineer

Reputation: 2607

grep and cut with one more spaces

I have a method in bash script that does something like this

status=$(docker service ls|grep $1|cut -f7 -d' '| grep -w "1/1")

The value $1=abc_mongodb1 or $1=abc_mongodb2 and so on. It tells me if string 1/1 exists it means my service is up. The problem happens when the output of docker service ls has different number of spaces because the names of services vary in length. How do I tell the delimiter in the cut part of the pipe to use one or more spaces. The following types of outputs are possible

Output of type1
`ID            NAME          MODE        REPLICAS  IMAGE
fw2qdrh38oeq  abc_mongodb2  replicated  1/1       mongo:3.4
l9mvn0wvqaxy  abc_mongodb1  replicated  1/1       mongo:3.4
pfjlpa29yb59  abc_mongodb3  replicated  1/1       mongo:3.4`

My cut command works fine in the above. It fails in the below case

Output of type 2(failure case)
ID            NAME                 MODE        REPLICAS  IMAGE
45uhn1au50ue  abc_deltaservice     replicated  1/1       abc-deltaservice:latest
cubbmpw657ib  abc_mongodb1         replicated  1/1       mongo:3.4
gil4c53jrvyc  abc_mongodb2         replicated  1/1       mongo:3.4
hy9ooec4rapd  abc_executionengine  replicated  1/1       abc-executionengine:latest
vocsigy76ab0  msc_mongodb3         replicated  1/1       mongo:3.4
ze4jg0f2y0jt  abc_kongdb           replicated  1/1       postgres:9.4

Upvotes: 1

Views: 507

Answers (2)

codeforester
codeforester

Reputation: 42999

Use awk which handles repeated spaces gracefully:

status=$(docker service ls | awk -v service=$1 '$2 == service { print $4 }' | grep -w "1/1")

You can eliminate grep by adding that check to awk:

status=$(docker service ls | awk -v service=$1 '$2 == service && $4 == "1/1" { print $4 }')

or, to make it a little more clear:

status=$(docker service ls | awk -v service=$1 -v state="1/1" '$2 == service && $4 == state { print $4 }')

Upvotes: 0

Kamil Piwowarski
Kamil Piwowarski

Reputation: 524

You can try to delete any additional spaces from input with sed before sending it as input to cut command

sed 's/ \+/\ /g'

this command will replace any sequence of more than one space to a single space

so your command will look something like:

status=$(docker service ls|grep $1|sed 's/ \+/\ /g'|cut -f7 -d' '| grep -w "1/1")

Upvotes: 1

Related Questions