3

I have a file named test which has two columns one having ID and other having status.

I want to loop through the file and print IDs where status have one particular value (e.g. 'ACTIVE').

I tried
cat test | while read line; do templine= $($line | cut -d ' ' -f 2);echo $templine; if [ $templine = 'ACCEPTED' ]; then echo "$templine"; fi done and some variation of above which obviously did not work.

Any help would be appreciated.

Abhijeet Shukla
  • 33
  • 1
  • 1
  • 5
  • `cat test | while read line; do templine= $($line | cut -d ' ' -f 2);echo $templine; if [[ $templine = 'ACCEPTED' ]]; then echo "$templine"; fi done ` above command treadted IDs as commands and started executing them – Abhijeet Shukla Feb 22 '16 at 09:36
  • 1
    Have you considered just `grep`ping the lines and then getting the column of the IDs only? – FelixJN Feb 22 '16 at 09:39
  • egrep "[^[:space:]]*[:space:]ACTIVE" | awk ' { print $1 } ' – Rui F Ribeiro Feb 22 '16 at 09:44
  • 2
    @RuiFRibeiro that would be `awk '$2 == "ACTIVE" { print $1 }'` ;-) – Stephen Kitt Feb 22 '16 at 09:50
  • Even better and more compact, I never remember to use awk´s BEGIN block. Thanks! – Rui F Ribeiro Feb 22 '16 at 09:52
  • @StephenKitt worked like a charm! Thanks, I am a newbie with Unix and was struggling with this for quite some time now. any idea why my query above did not work ? – Abhijeet Shukla Feb 22 '16 at 09:54
  • your query didn't work because you had just `templine=$($line | cut ...)` rather than `$(echo "$line" | cut ...)` or, better yet: `$(printf '%s' "$line" | cut ...)`. your version of the command attempted to execute the command contained in `$line` - which almost certainly doesn't exist. you probably also wanted `cat test | while IFS= read line ; do ...` so that `read` assigns the entire input line to `$line` rather than just the first field. but as has been mentioned awk is a better tool for this job. – cas Feb 22 '16 at 10:00
  • See also [Why is using a shell loop to process text considered bad practice?](http://unix.stackexchange.com/q/169716) – Stéphane Chazelas Feb 22 '16 at 10:45
  • @cas : Thanks for your suggestion `cat test | while read line; do templine= $(echo "$line" | cut -f 2) ; done;` I made the changes as suggested but now it's executing the command contained in templine – Abhijeet Shukla Feb 22 '16 at 10:49

2 Answers2

3

When you need to manipulate data in fields, awk tends to fit the bill quite nicely:

awk '$2 == "ACTIVE" { print $1 }' test

This reads each line of test, splits it into fields, then checks if the second one ($2) is ACTIVE; if so, it prints the first field.

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • another variation, if you want a regexp search on field 2 rather than an exact match, is: `awk '$2 ~ /ACTIVE/ { print $1 }'` – cas Feb 22 '16 at 09:55
  • @StephenKitt worked like a charm! Thanks, I am a newbie with Unix and was struggling with this for quite some time now. any idea why my query above did not work ? – Abhijeet Shukla Feb 22 '16 at 09:55
  • 2
    @AbhijeetShukla, the main problem in your attempt is `templine= $($line | cut -d ' ' -f 2)`, which runs `$line`; to fix that, `echo $line` instead, and remove the space after the `=`: `templine=$(echo $line | cut -d ' ' -f 2)`. If you want to use `read` you can use that to split the input into fields: `while read id status; do if [ "$status" = "ACTIVE" ]; then ...; fi; do`. – Stephen Kitt Feb 22 '16 at 09:58
3

see below example i hope its helpful for you

g=7

echo $g

output: 7

h=`echo $g`

echo $h

i hope its helpful for you see below image

enter image description here

Tiger
  • 648
  • 7
  • 12
  • 25