简体   繁体   中英

How to use awk to print “hello” if pattern is found

I want to search for a pattern in a tab-separated .txt-file and, if the pattern is found in a line, print the third field of that line.

I only need to find the first occurence in the line, since the pattern appears only once for sure.

Structure of .txt-file:

XXX01 foo target1
XXX02 bar target2
XXX03 foobar target3

My first idea was, to print "hello", if the pattern is found, to control, if my code works. I also included echos of the variables I pass to my bash script.

Command line call and Script:

$ ./script.sh file.txt foo

#!/bin/bash
file=$1
pattern=$2


awk '/"$pattern"/{print "hello"}' "$file"

echo "$file"
echo "$pattern"

As far as I found it for awk, to get the third field printed, I would have to substitute print "hello" with print "\\$2".

But printing "hello" already does not work:

Actual output:

file.txt
foo

Desired output:

hello (respectively target1)
file.txt
foo 

And I also checked for sure, that "foo" is in the file.txt

Progress (see comments and answer please):

#!/bin/bash

awk -v p="$2"'$2=="$p"{print "hello",$3}' "$1"

echo "$1"
echo "$2"

new output:

awk: 1:unexpected character '.'
file.txt
foo

I believe you want something like:

$ ./script.sh file.txt foo

#!/bin/bash
file=$1
pattern=$2


awk -v pattern=$pattern'$2==pattern{print "hello",$3}' "$file"

echo "$file"
echo "$pattern"

Here we get rid of the loop since awk checks every record when it is fed a file. We also use the -v flag to pass in the $pattern variable into the awk script. Then we check that the second field $2 is pattern and print "hello" as well as the contents of the third field $3 .

You could change that awk condition to $2~/pattern/ to truly utilize regex if you want but I suspect it will print the 1st and 3rd line as foo shows up in both.

If you want to check if your pattern exists in anywhere in the line then you can drop the $2~ so it's just '/pattern/{print "hello",$2} .

Look:

$ x="foo"'bar' && echo "$x"
foobar

$ x="foo" 'bar' && echo "$x"
-bash: bar: command not found

Your script is:

awk -v p="$2"'$2=="$p"{print "hello",$3}' "$1"

so guess what not leaving a space between -vp="$2" and '$2=="$p" is doing. Right, it's concatenating them so don't do that - add a space:

awk -v p="$2" '$2=="$p"{print "hello",$3}' "$1"

The unexpected . btw was the . in your file name file.txt when awk was trying to evaluate the string file.txt as its cript due to the concatenation consuming the actual script into the assignment to p .

Now to actually USE the variable p in the comparison you'd have to use it as a variable instead of putting it inside a string:

awk -v p="$2" '$2==p{print "hello",$3}' "$1"

The above simply answers your question about the syntax error. To actually do what you WANT would require one of these, depending on whether you want a string or regexp match and whether you want partial or full matching:

awk -v p="$2" '$2==p{print "hello",$3}' "$1"
awk -v p="$2" '$2~p{print "hello",$3}' "$1"
awk -v p="$2" '$2~"\\<"p"\\>"{print "hello",$3}' "$1"

or some other solution depending on your so far unstated requirements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM