Home > Software engineering >  New to bash and stumped how to finish this. Only able to make it work for one line and does not cont
New to bash and stumped how to finish this. Only able to make it work for one line and does not cont

Time:04-29

Trying to grep regex from string within txt and echo a status. .txt looks something like this:

something something something name1 something something Available something something something
something something something name2 something something Available something something something
something something something name3 something something Available something something something
something something something name4 something something No status something something something
something something something name5 something something No status something something something

I am able to find the pattern in first line and echo the status

cat status.txt | grep -o $name>/dev/null ; cat status.txt | grep -o "No status">/dev/null && echo $name is offline || echo $name is online
name1 is online

This is working correctly; but how would I go about making this work on all lines so that I would get

name1 is online
name2 is online
name3 is online
name4 is offline
name5 is offline

I have looked up and down and can not figure this out. I have also tried variations of sed and awk. nothing works. maybe I should be using python for this or something. Thanks for any help!

CodePudding user response:

Using awk

$ awk '{if ($7 == "Available") print $4 " is online"; else print $4 " is offline"}' status.txt
name1 is online
name2 is online
name3 is online
name4 is offline
name5 is offline

CodePudding user response:

Don't use grep for this. Read the file line by line, extracting the information you need from it.

while read -r x y z name rest; do
    case "$rest" in
        *Available*) printf '%s is online\n' "$name" ;;
        *"No status"*) printf '%s is offline\n' "$name ;;
    esac
done < status.txt

CodePudding user response:

A similar awk implementation using a ternary to control output based on the seventh field can be written as:

awk '{print $4 " is " ($7=="Available" ? "online" : "offline")}' file

Example Use/Output

With your data in file, you would have:

$ awk '{print $4 " is " ($7=="Available" ? "online" : "offline")}' file
name1 is online
name2 is online
name3 is online
name4 is offline
name5 is offline

Problems With Your Approach

The are a number of the same inefficiencies with your approach, specifically when you do:

cat status.txt | grep -o ...; cat status.txt | grep -o ...

You are committing two UUOc's in a row. Unless you are concatenating two (or more) files, cat file is an Unnecessary Use Of cat (UUOc) and should be avoided. Instead just read the file or use redirection. For example:

grep -o ... status.txt; grep -o ... status.txt ...

Every pipe '|' spawns a separate subshell to tie the output of one process (stdout) to the input of the next (stdin). There is no need to cat to grep. grep can read the file directly or read it on stdin via redirection, e.g. grep ... file or grep ... < file.

  • Related