I have a file list.txt containing data like this
hvar-mp-log.hvams europe#gmail.com
mvar-mp-log.mvams japan#gmail.com
mst-mp-log.mst korea#gmail.com
pif-mp-log-pif atlas#gmail.com
I need to match the string in the list.txt and print the matched string second column data.
if string=mst-mp-log.mst print korea#gmail.com.
I can match string like this example
grep -q "$string" list.txt
how to print matched string mail id. expected output should be like korea#gmail.com
With awk:
string="mst-mp-log.mst"
awk -v var="$string" '$1 == var {print $2}' list.txt
Or, if your grep command is already returning the correct lines, perhaps:
grep -q "$string" list.txt | awk '{print $2}'
Here is a solution using individual commands in a pipe:
$ grep '^mst-mp-log.mst ' list.txt | tr -s ' ' | cut -d ' ' -f 2
korea#gmail.com
Related
I have data in file.txt as follows
BRAD CHICAGO|NORTH SAMSONCHESTER|
CORA|NEW ERICA|
CAMP LOGAN|KINGBERG|
NCHICAGOS|ESTING|
CHICAGO|MANKING|
OCREAN|CHICAGO|
CHICAGO PIT|BULL|
CHICAGO |NEWYORK|
Question 1:
I want to search for the exact match for word "CHICAGO" in first column and print second column.
Output should look like:
MANKING
NEWYORK
Question 2:
If multiple matches found then can we limit the out to only one ? so that the output will be only MANKING or NEWYORK
I tried below
grep -E -i "^CHICAGO" file.txt | awk -F '|' '{print $2}'
but i am getting below output
MANKING
BULL
NEWYORK
Expected output for Question 1:
MANKING
NEWYORK
Expected output for Question 2:
MANKING
Here are some more ways:
Using grep and cut:
grep "^CHICAGO|" file.txt | cut -d'|' -f2
Using awk
awk -F"|" '/^CHICAGO\|/{print $2}' file.txt
For question 2 simply pipe it to head, i.e:
grep "^CHICAGO|" file.txt | cut -d'|' -f2 | head -n1
Similarly for the awk command.
how about an awk solution?
awk -F'|' '$1 == "CHICAGO"{print $2}' file
to only print one output, exit once you have a match, i.e.
awk -F'|' '$1 == "CHICAGO"{print $2; exit}' file
Making that more generic, you can pass in a variable, i.e.
awk -v trgt="CHICAGO" -F'|' '{targ="^" trgt " *$"; if ( $1 ~ targ ) {print $2}}' file
The " *$" regex limits the match to zero or more trailing spaces without any extra chars at the end of the target string. So this will meet your criteria to match skip matching CHICAGO PIT|BULL.
AND this can be further reduced to
awk -v trgt="CHICAGO" -F'|' '{ if ( $1 ~ "^" trgt " *$" ) {print $2}}' file
constructing the regex "in-place" in with the comparison.
So you could use more verbose variable names to "describe" how the regex is being constructed from the input and the regex "wrappers" (as in the 3rd example) OR, you can just combine the input variable with the regex syntax in place. That is just a matter of taste or documentation conventions.
You might want to include a comment to explain you are constructing a regex test that would look like the $1 ~ /^CHICAGO *$/.
IHTH
I have a .txt file having files names as
z1.cap
z2.cap
z3.cap
z4.cap
Sample data present in these files are like shown below,
OTR 25896 PAT210 $TREMD DEST
OFR 21475 NAT102 #TREMD DEST
then I'm using below code to print desired values from files.
while read file_name
do
echo "progressing with file :${file_name}"
cat ${file_name} | grep "PAT210" | awk -F' ' '$5 == "(DEST" { print $file_name, $1}' | uniq >> OUTPUT_FILE
Now I want output which consists of 2 fields like,
z1.cap OTR
z2.cap OFR
and so on...
But i'm getting ouputs like,
- OTR
- OFR
Any help is aprreciated, Thanks.
To access the filename that awk is currently processing use the builtin variable FILENAME
To bind other shell variables from your shell to variables in awk use:
awk -v var1=$shvar1 -v var2=$shvar2 'your awk code using var1 and var2'
Assuming files.txt contains your list of files and with zero understanding of what exactly you are trying to achieve:
for file_name in $(cat files.txt)
do
echo "progressing with file :${file_name}"
awk -F' ' '($5 == "DEST") && ($3=="PAT210") { print FILENAME, $1}' $file_name | uniq >> OUTPUT_FILE
done
I removed the cat and incorporated the grep into your awk. The cat was unnecessary since awk can read the file itself.
You can remove the for loop entirely by saying
awk -F' ' '($5 == "DEST") && ($3=="PAT210") { print FILENAME, $1}' $(<files.txt) | uniq >> OUTPUT_FILE
The $(<files.txt) will send each filename to awk.
I have some file xxx.conf in text format. I have some text "disablelog = 1" in this file.
When I use
grep -r "disablelog" oscam.conf
output is
disablelog = 1
But i need only value 1.
Do you have some idea please?
one way is to use awk to print just the value
grep -r "disablelog" oscam.conf | awk '{print $3}'
you could also use sed to replace diablelog = with empty
grep -r 'disablelog' oscam.conf | sed -e 's/disablelog = //'
If you also want to get the lines with or without space before and after = use
grep -r 'disablelog' oscam.conf | sed 's/disablelog\s*=\s*//'
above command will also match
disablelog=1
Assuming you need it as a var in a script:
#!/bin/bash
DISABLELOG=$(awk -F= '/^.*disablelog/{gsub(/ /,"",$2);print $2}' /path/to/oscam.conf)
echo $DISABLELOG
When calling this script, the output should be 1.
Edit: No matter wether there is whitespace or not between the equals sign and the value, the above will handle that. The regex should be anchored in either way to improve performance.
Try:
grep -r "disablelog" oscam.conf | awk -F= '{print $2}'
Just for fun a solution without awk
grep -r disablelog | cut -d= -f2 | xargs
xargs is used here to trim the whitespace
I have a text files with a line like this in them:
MC exp. sig-250-0 events & $0.98 \pm 0.15$ & $3.57 \pm 0.23$ \\
sig-250-0 is something that can change from file to file (but I always know what it is for each file). There are lines before and above this, but the string "MC exp. sig-250-0 events" is unique in the file.
For a particular file, is there a good way to extract the second number 3.57 in the above example using bash?
use awk for this:
awk '/MC exp. sig-250-0/ {print $10}' your.txt
Note that this will print: $3.57 - with the leading $, if you don't like this, pipe the output to tr:
awk '/MC exp. sig-250-0/ {print $10}' your.txt | tr -d '$'
In comments you wrote that you need to call it in a script like this:
while read p ; do
echo $p,awk '/MC exp. sig-$p/ {print $10}' filename | tr -d '$'
done < grid.txt
Note that you need a sub shell $() for the awk pipe. Like this:
echo "$p",$(awk '/MC exp. sig-$p/ {print $10}' filename | tr -d '$')
If you want to pass a shell variable to the awk pattern use the following syntax:
awk -v p="MC exp. sig-$p" '/p/ {print $10}' a.txt | tr -d '$'
More lines would've been nice but I guess you would like to have a simple use awk.
awk '{print $N}' $file
If you don't tell awk what kind of field-separator it has to use it will use just a space ' '. Now you just have to count how many fields you have got to get your field you want to get. In your case it would be 10.
awk '{print $10}' file.txt
$3.57
Don't want the $?
Pipe your awk result to cut:
awk '{print $10}' foo | cut -d $ -f2
-d will use the $ als field-separator and -f will select the second field.
If you know you always have the same number of fields, then
#!/bin/bash
file=$1
key=$2
while read -ra f; do
if [[ "${f[0]} ${f[1]} ${f[2]} ${f[3]}" == "MC exp. $key events" ]]; then
echo ${f[9]}
fi
done < "$file"
I am using grep recursive to search files for a string, and all the matched files and the lines containing that string are print on the terminal. But is it possible to get the line numbers of those lines too??
ex: presently what I get is /var/www/file.php: $options = "this.target", but what I am trying to get is /var/www/file.php: 1142 $options = "this.target";, well where 1142 would be the line number containing that string.
Syntax I am using to grep recursively is sudo grep -r 'pattern' '/var/www/file.php'
One more question is, how do we get results for not equal to a pattern. Like all the files but not the ones having a certain string?
grep -n SEARCHTERM file1 file2 ...
Line numbers are printed with grep -n:
grep -n pattern file.txt
To get only the line number (without the matching line), one may use cut:
grep -n pattern file.txt | cut -d : -f 1
Lines not containing a pattern are printed with grep -v:
grep -v pattern file.txt
If you want only the line number do this:
grep -n Pattern file.ext | gawk '{print $1}' FS=":"
Example:
$ grep -n 9780545460262 EXT20130410.txt | gawk '{print $1}' FS=":"
48793
52285
54023
grep -A20 -B20 pattern file.txt
Search pattern and show 20 lines after and before pattern
grep -nr "search string" directory
This gives you the line with the line number.
In order to display the results with the line numbers, you might try this
grep -nr "word to search for" /path/to/file/file
The result should be something like this:
linenumber: other data "word to search for" other data
When working with vim you can place
function grepn() {
grep -n $# /dev/null | awk -F $':' '{t = $1; $1 = $2; $2 = t; print; }' OFS=$':' | sed 's/^/vim +/' | sed '/:/s// /' | sed '/:/s// : /'
}
in your .bashrc and then
grepn SEARCHTERM file1 file2 ...
results in
vim +123 file1 : xxxxxxSEARCHTERMxxxxxxxxxx
vim +234 file2 : xxxxxxSEARCHTERMxxxxxxxxxx
Now, you can open vim on the correspondending line (for example line 123) by simply copying
vim +123 file1
to your shell.