Using grep to find a line and print only 2 words from that line - linux

I'm new to linux and i decided to learn shell scripting. I have created a file data.txt that contains the following text:
12345 Nick Abrams A 10900
67890 George Kennedy I 20000
(text goes on...)
The first field is a card's pin number, the second is the name of the client, third is surname, fourth indicates whether a card is active (or inactive) and the last field is the client's balance. I need to write a script that receives the client's pin from keyboard and if that pin is written in the text file then the script should print the client's name and surname on the screen. I have used grep like this
grep "^$pin" data.txt
But it returns all the details of a client. I only need to print the second and third field and ignore everything else. Is there any parameter to isolate the words i need?

Could you please try following and let me know if this helps you.
cat script.ksh
echo "Please enter your choice:"
read value
awk -v val="$value" '$1==val{print $2,$3}' Input_file
EDIT: Adding a solution with grep and cut in a script too here.
cat script.ksh
echo "Please enter your choice:"
read value
grep "$value" Input_file | cut -d" " -f2,3

Better use sed :
sed -n 's/^'"$pin \([^ ]* [^ ]*\).*"'/\1/p' data.txt
This command match a line that start by $pin, and write only part that follow regex between \( and \)

#!/bin/bash
echo "Enter PIN, please"
read pin
grep "${pin}" pins.txt | awk '{print $2" "$3}'
Input: 12345
Output: Nick Abrams
Or with cut:
#!/bin/bash
echo "Enter PIN, please"
read pin
grep "${pin}" pins.txt | cut -d' ' -f2,3

Related

Printing value after "=" in linux

I have a requirement from the below line
/opt/update/data/abc.prop=15698
I need to display the output as below:
15698
Assuming you want to extract everything after the equals sign:
echo /opt/update/data/abc.prop=15698 | sed s/.*=//
The sed command matches all characters up to and including the equals sign and replaces it with nothing.
got the answer after trying the below. If any simpler one, please suggest
cat s1.txt|grep -o "=.*"|sort -u|grep -Po '\K[^=]+'
echo /opt/update/data/abc.prop=15698 | awk -F"=" '{print $2}'
awk can be used as a field separator and output will be in the second field.

Using cat and grep to print line and its number but ignore at the same time blank lines

I have created a simple script that prints the contents of a text file using cat command. Now I want to print a line along with its number, but at the same time I need to ignore blank lines. The following format is desired:
1 George Jones Berlin 2564536877
2 Mike Dixon Paris 2794321976
I tried using
cat -n catalog.txt | grep -v '^$' catalog.txt
But I get the following results:
George Jones Berlin 2564536877
Mike Dixon Paris 2794321976
I have managed to get rid of the blank lines, but line's number is not printed. What am I doing wrong?
Here are the contents of catalog.txt:
George Jones Berlin 2564536877
Mike Dixon Paris 2794321976
Your solution doesn't work because cat -n catalog.txt is already giving you non-blank lines.
You can pipe grep's output to cat -n:
grep -v '^$' yourFile | cat -n
Example:
test.txt:
Hello
how
are
you
?
$ grep -v '^$' test | cat -n
1 Hello
2 how
3 are
4 you
5 ?
At first glance, you should drop the file name in the command line to grep to make grep read from stdin:
cat -n catalog.txt | grep -v '^$'
^^^
In your code, you supplied catalog.txt to grep, which made it read from the file and ignore its standard input. So you're basically grepping from the file instead of the output of cat piped to its stdin.
To correctly ignore blank lines the prepend line numbers, switch the order of grep and cat:
grep -v '^$' catalog.txt | cat -n
Another awk
$ awk 'NF{$0=FNR " " $0}NF' 48488182
1 George Jones Berlin 2564536877
3 Mike Dixon Paris 2794321976
The second line was blank in this case.
single, simple, basic awk solution could help you here.
Solution 1st:
awk 'NF{print FNR,$0}' Input_file
Solution 2nd: Above will print line number including the line number of NULL lines, in case you want to leave empty lines line number then following may help you in same.
awk '!NF{FNR--;next} NF{print FNR,$0}' Input_file
Solution 3rd: Using only grep, though output will have a colon in between line number and the line.
grep -v '^$' Input_file | grep -n '.*'
Explanation of Solution 1st:
NF: Checking condition here if NF(Number of fields in current line, it is awk's out of the box variable which has the value of number of fields in a line) is NOT NULL, if this condition is TRUE then following the actions mentioned next to it.
{print FNR,$0}: Using print function of awk here to print FNR(Line number, which will have the line's number in it, it is awk's out of box variable) then print $0 which means current line.
By this we satisfy OP's both the conditions of leaving empty lines and print the line numbers along with lines too. I hope this helps you.

Bash Advanced grep solution

I have a file.txt on my Linux which looks like the following structure:
file.txt:
full name
E-mail: email#email.com
Phone: 0123456789
full name
email#email.com
01/23456789
full name
e: email#email.com
00-223-445-56
.
.
.
etc
Or only the name entry and phone number or e-mail address
I would like to use grep to when I start
./myprogram.sh file.txt
list all of the E-mail addresses and Phone numbers from the file. How can I do that if the file.txt looks like this?
you can start wit something simple like that:
cat file.txt | grep -E "(#|[0-9]+)"
it gives you everything with an # (so emails) and everything with numbers (so phone numbers). you can use more advanced regular expressions for better search (emails and phone numbers do have stricter rules...) but thats the idea.
egrep "#|[0-9]"
will match only lines that contain an "#" or at least one digit. Your example says that the name line does not contain digits.
It isn't quite clear which format you expect as an output. If you want to have e-mail addresses and phone numbers separated (is it that what you want? The connection: e-mail address <-> phone number would be kind of confused then) you could also use (GNU) sed:
sed -n -e '1 {s/\(.*\)/e-mail:\n\1/; P;};' \
-e '/#/ s/\(.\+[ \\\t]\)\{0,1\}\(.\+\)#\(.\+\)/\t\2\#\3/p;' \
-e '/[0-9]\+$/ H; $ {x; s/\n\([^0-9]*\)\([0-9]\+\)/\n\t\2/g; s/\(.*\)/\nphone:\n\1/p;}'
file.txt
Do you actually want to use grep, or are you just using the phrase "use grep" to mean "filter". Assuming the latter (since grep is the wrong tool for this), and assuming that each record has a single email address in the final column of the 2nd line and a phone number in the final column of the 3rd line, and that each record is separated by a line with no extra whitespace, you could do:
<file.txt awk '{print $NF}' | awk '{print $2,$3}' FS='\n' RS=
You could do it with a single awk invocation, but this is simpler and probably sufficient.
That's a job for awk, not grep:
$ awk '(NR%4)~/^[23]$/{print $NF}' file
email#email.com
0123456789
email#email.com
01/23456789
email#email.com
00-223-445-56
$ awk '(NR%4)~/^[23]$/{printf "%s%s", $NF, (++c%2?OFS:ORS)}' file
email#email.com 0123456789
email#email.com 01/23456789
email#email.com 00-223-445-56
$ awk '(NR%4)==2{print $NF}' file
email#email.com
email#email.com
email#email.com
$ awk '(NR%4)==3{print $NF}' file
0123456789
01/23456789
00-223-445-56
Take your pick, it's all trivial...

using linux cat and grep command

I am having following syntax for one of my file.Could you please anyone explain me what is this command doing
path = /document/values.txt
where we have different username specified e.g username1 = john,username2=marry
cat ${path} | grep -e username1 | cut -d'=' -f2`
my question here is cat command is reading from the file value of username1 but why why we need to use cut command?
Cat is printing the file. The file has username1=something in one of the lines. The cut command splits this and prints out the second argument.
your command was not written well. the cat is useless.
you can do:
grep -e pattern "$path"|cut ...
you can of course do it with single process with awk if you like. anyway the line in your question smells not good.
awk example:
awk -F'=' '/pattern/{print $2}' inputFile
cut -d'=' -f2`
This cut uses -d'=' that means you use '=' as 'field delimiter' and -f2 will take only de second field.
So in this case you want only the value after the "=" .

how to print a line resulting from a search keyword in a column using grep command,

This is an example of a filename.csv file
"Sort Order","Common Name","Formal Name","Type","Sub Type"
"1","Afghanistan","Islamic State of Afghanistan","Independent State"
"2","Albania","Republic of Albania","Independent State"
"3","Algeria","People's Democratic Republic of Algeria","Independent State"
"4","Andorra","Principality of Andorra","Independent State"
"5","Angola","Republic of Angola","Independent State"
So what is the grep command to search for angola in common name and print it like this:
"5","Angola","Republic of Angola","Independent State"
I know that we can use:
grep '"Algeria"' filename.csv
However, what if I am being more specific. Let's say Algeria might exist in other column however, we only need to print the one in Common Name column.
I tried
grep '"Common Name | Algeria"' filename.csv
Seems not to work.
You could try the below grep command to print the lines which contains the string Angola in the second column.
grep -E '^"[^"]*","Angola"' file
This could be easily done through awk,
awk -F, '$2=="\"Angola\""' file
try awk
awk -F"," '$2~/Algeria/' file
Use cut command,
grep Algeria filename.csv|cut -f2 -d','|awk -F '[""]' '{print $2}'
Output:
Algeria
Here is the explanation of all command I have added with your grep and discarded some unnecessary quotes you used in it.
cut command:
-f It will extract 2nd column depending on delimiter
-d It will choose delimiter i.e.: which is here ,
awk command:
It will extract value between two "" (block quotes) and print it.

Resources