# Getting only specific data based on name in text file

Let's say if my text file contains:

101    Adam
201    Clarie
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.

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


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

• (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"]') Oct 14 '17 at 10:10
• good point about backslash characters :) Oct 14 '17 at 10:31

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? 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. Oct 14 '17 at 6:38 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 $. Oct 14 '17 at 7:10
• @BLayer I was just going off the sample input; updated to handle the cases you mention. Oct 14 '17 at 7:24
• 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. Oct 14 '17 at 7:30