How to Use Grep to Match But Without Printing the Matches

How can I use grep to match but without printing the matches?

Use grep -q (quiet)

/var/folder/program.exe -L parameters |
grep -q "text_to_filter" && echo 'SomeText' > '/tmp/Log.txt'

As per man grep:

-q, --quiet, --silent
Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error
was detected. Also see
the -s or --no-messages option.

How to grep the exact match and print only that match

This should be a job for awk, could you please try following, written and tested with shown samples in GNU awk. Please mention absolute path in place of . to get run it for any directory in find command.

The output should be filename : matched string(s) : line number for all files.

You could run following find command:

find . -type f -exec awk -f script.awk {} +

Where script.awk is as follows:

cat script.awk
BEGIN{ OFS=" : " }
NF{
val=""
for(i=1;i<=NF;i++){
if($i~/abcxyz/){
val=(val?val OFS:"")$i
}
}
if(val){
print FILENAME,val,FNR
}
}

For your shown samples(considering empty lines in it), sample output will be as follows.

Input_file  :  abcxyz.fgh     :  1
Input_file : gfhj.abcxyz : 3
Input_file : abcxyz.sh : 5
Input_file : abcxyz.fsdghj : 7

Explanation: Adding detailed explanation for above.

BEGIN{ OFS=" : " }              ##Setting OFS to space colon space in BEGIN section of this program.
NF{ ##Checking condition if line is NOT empty then do following.
val=""
for(i=1;i<=NF;i++){ ##Traversing through all field values here.
if($i~/abcxyz/){ ##checking condition if field is matching abcxyz then do following.
val=(val?val OFS:"")$i ##Creating val which has value of current field and keep adding it.
}
}
if(val){ ##Checking condition if val is NOT NULL then do following.
print FILENAME,val,FNR ##Printing FILENAME val and FNR here.
}
}
'

grep, else print message for no matches

You don't need a loop at all if you simply want to display a message when there's no match. Instead you can use grep's return code. A simple if statement will suffice:

if ! grep "regex" "filepath"; then
echo "no match" >&2
fi

This will display the results of grep matches (since that's grep's default behavior), and will display the error message if it doesn't.

A popular alternative to if ! is to use the || operator. foo || bar can be read as "do foo or else do bar", or "if not foo then bar".

grep "regex" "filepath" || echo "no match" >&2

Negative matching using grep (match lines that do not contain foo)

grep -v is your friend:

grep --help | grep invert  

-v, --invert-match select non-matching lines

Also check out the related -L (the complement of -l).

-L, --files-without-match only print FILE names containing no match

Bash grep output filename and line no without matches

You were pointing it well with cut, only that you need the : field separator. Also, I think you need the first and second group. Hence, use:

grep -Hn 'pattern' files* | cut -d: -f1,2

Sample

$ grep -Hn a a*
a:3:are
a:10:bar
a:11:that
a23:1:hiya

$ grep -Hn a a* | cut -d: -f1,2
a:3
a:10
a:11
a23:1

grep - print line before, don't print match


awk '!/foo/ { line = $0 }
/foo/ { print line }' foo.txt

The first clause saves each non-foo line in a variable. The second clause prints the most recent saved line when the line matches foo.

This also works (and handles the case where you have two foo lines in a row):

awk '/foo/ {print line}
{line = $0}' foo.txt

With grep you can do:

grep -B 1 foo foo.txt | grep -vE 'foo|^--$'

The second command filters out the foo lines and the dividers that are printed between the matching blocks.

grep obtains pattern from a file but printing not only the whole match word

The man page for grep says the following about the -w switch:

-w, --word-regexp

Select only those lines containing matches that form whole words. The test is that the matching substring must either be at the beginning of the line, or preceded by a non-word constituent character. Similarly, it must be either at the end of the line or followed by a non-word constituent character. Word-constituent characters are letters, digits, and the underscore.

In your case, all three lines start with "CA1C-", which meets the conditions of being at the beginning of the line, and being followed by a non-word constituent character (the hyphen).

I would do this with a loop, reading lines manually from check.txt:

cat check.txt | while read line; do grep "^$line " file.txt; done
CA1C 2637 green

This loop reads the lines from check.txt, and searches for each one at the start of a line in file.txt, with a following space.

There may be a better way to do this, but I couldn't get -f to actually consider whitespace at the end of a line of the input file.

How can I make grep do a word match , but without periods being treated as a word separator?

Assuming this is your input file:

cat file

5.3.236.113681.2225191122.986.3705653211.104 4
5.3.236.113681.2225191122.986.3705653211.104.3402 45
5.3.236.0.1.20549687.20.93.9.2.234266672113.4455 2
5.3.236.113681.5829104.986.3705653211.119 8
5.3.236.2.01107.50.01.24.48685.30000018053113560818700000112 172
4 5.3.236.113681.2225191122.986.3705653211.104
45 5.3.236.113681.2225191122.986.3705653211.104.3402

If you have gnu-grep then you can use this PCRE regex with look-arounds:

grep -P '(?<!\S)5\.3\.236\.113681\.2225191122\.986\.3705653211\.104(?!\S)' file

5.3.236.113681.2225191122.986.3705653211.104 4
4 5.3.236.113681.2225191122.986.3705653211.104

Here:

  • (?<!\S): is a negative lookbehind regex to assert that we don't have a non-whitespace at a position before the current position
  • (?!\S): is a negative lookahead regex to assert that we don't have a non-whitespace at a position after the current position

Here is POSIX complaint awk solution:

awk -v s='5.3.236.113681.2225191122.986.3705653211.104' '{
for (i=1; i<=NF; ++i) if ($i == s) {print; next}}' file

5.3.236.113681.2225191122.986.3705653211.104 4
4 5.3.236.113681.2225191122.986.3705653211.104


Related Topics



Leave a reply



Submit