2

Let's say if my text file contains:

101    Adam
201    Clarie
502    Adam
403    Tom

and i want to write a command in the shell to only give me the numbers based of a specific name. For example, only output the number for the name 'Adam' would give:

101
502

I was thinking of something like:

cut -f 1 Data_1 | grep "Adam"

but it doesn't work. Data_1 is the filename. 1 refers to the first column. I'm new to Unix so I'll appreciate some feedback on this.

2

First you have the order of grep/cut backwards. And, unless those are actual tabs (as in Tab) separating your columns (I can't tell) you also need to specify that normal whitespace (as in Space) is your delimeter.

grep Adam Data_1 | cut -f1 -d' '

If you are using tabs then leave off -d' '.

Generally speaking try one thing at a time while building a compound command like this. What do you see when you do cut alone? Does it look like applying grep to it makes sense? If not then rethink things.

And always give the man page for each command a good read.


Bonus: Here's a sed command to do the same thing:

sed -n 's/^\(.*\)\t\+Adam$/\1/p' Data_1

This goes through each line in the file but prints only those that end with one or more tabs and your search string. Then, before printing, it strips off those same tabs and search string.

  • @B Layer yes those are tabs. if so, i won't need to specify the delimiter am i correct? – Electric Oct 14 '17 at 6:37
  • Right. If you look at the -d flag in man cut you'll see that the default is tab so nothing extra required. – B Layer Oct 14 '17 at 6:38
3

You can use single grep with perl look around extension via -P option:

grep -Po '.*(?=Adam)' file

That will print everything in the line up to the word Adam.

If you want only numbers, excluding whitespaces etc, then:

grep -Po '[0-9]*(?=.*Adam)' file
3

Would suggest to use awk for this

  • Default input field separator is one or more consecutive white-spaces, so no need to worry about space/Tab separations
  • Easier to compare fixed strings (i.e less prone to regex meta characters - need to take care in constructing string with quotes and the backslash character. See also Escape Sequences)


$ cat ip.txt
101    Adam
201    Clarie
502    Adam
403    Tom

$ # check if 2nd column value is Adam (wont match MAdam, Adama, etc)
$ # use $NF instead of $2 to check against last column
$ awk '$2=="Adam"{print $1}' ip.txt
101
502

$ # using variable instead of string constant
$ awk -v name='Adam' '$2==name{print $1}' ip.txt
101
502

$ # passing shell variable
$ n='Tom'
$ awk -v name="$n" '$2==name{print $1}' ip.txt
403
  • 1
    (speaking of meta characters, note that using -v would still cause problems with backslash characters. Compare awk -v name='\foo\bar' '$1 == name' with name='\foo\bar' awk '$1 == ENVIRON["name"]') – Stéphane Chazelas Oct 14 '17 at 10:10
  • good point about backslash characters :) – Sundeep Oct 14 '17 at 10:31
2

Simple approach with Awk:

awk '/ Adam$/ {print $1}' file                                             
101
502
  • This will match any line with Adam. What if someone had a name like "Adama" or "Adamina" or "Adamantite" ;) (I'm sure I've seen one of the first two before). For the sake of a beginner OP a stricter search criteria might be a good idea. Even just ending it with $. – B Layer Oct 14 '17 at 7:10
  • @BLayer I was just going off the sample input; updated to handle the cases you mention. – jasonwryan Oct 14 '17 at 7:24
  • 1
    Totally hear you w/r/t the sample input. It's good to go the extra mile for inexperienced users is my thinking. Thanks for the edit. – B Layer Oct 14 '17 at 7:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.