Cut the GREP command in Linux - linux

Okay so i have a variable called search which holds the string "Find this Code - Now". I want to search for that code and if it finds it the system would reply with true or something on those lines, if it doesn't then it just exits the script with error.
I tried to use grep but i couldn't figure out how to cut only what was searched for so i could run an if else statement

You can use the -q switch and check the exit status of grep, i.e. something like grep -q $var <file> && echo "true".

I tried to use grep but i couldn't figure out how to cut only what was searched for so i could run an if else statement
Grep has a switch --only-matching
-o, --only-matching show only the part of a line matching PATTERN

> X="not gonna find it"
> grep -qR "$X" .; echo $?
1
> X="Find this Code - Now"
> grep -qR "$X" .; echo $?
0

Related

How to use return status value for grep?

Why isn't my command returning "0"?
grep 'Unable' check_error_output.txt && echo $? | tail -1
If I remove the 'echo $?' and use tail to get the last occurrence of 'Unable' in check_error_output.txt it returns correctly. If I remove the tail -1, or replace it the pipe with && it returns as expected.
What am I missing?
The following way achieves what you're wanting to do without the use of pipes or sub shells
grep -q 'Unable' check_error_output.txt && echo $?
The -q flag stands for quiet / silent
From the man pages:
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. (-q is specified by POSIX.)
This is still not fail safe since a "No such file or directory" error will still come up both ways.
I would instead suggest the following approach, since it will output either type of return values:
grep -q 'Unable' check_error_output.txt 2> /dev/null; echo $?
The main difference is that regardless of whether it fails or succeeds, you will still get the return code and error messages will be directed to /dev/null. Notice how I use ";" rather than "&&", making it echo either type of return value.
use process Substitution:
cat <(grep 'Unable' check_error_output.txt) <(echo $?) | tail -1
The simplest way to check the return value of any command in an if statement is: if cmd; then. For example:
if grep -q 'Unable' check_error_output.txt; then ...
I resolved this by adding brackets around the grep and $?
(grep 'Unable' check_error_output.txt && echo $?) | tail -1

Searching a string in shell script

I am trying to learn shell script. So sorry if my question is so simple.
I am having a file called one.txt and if either strings 1.2 or 1.3 is present in the string then I have to display the success message else the failure message.
The code I tried is follows,
#!/bin/bash
echo "checking"
if grep -q 1.2 /root/one | grep -q 1.3 /root/one; then
echo " vetri Your NAC version"
fi
What I am doing wrong here ?
You can also include the OR in your grep pattern like so:
grep '1.2\|1.3' /root/one
details here
Update:
as twalberg pointed out in the comment, my answer was not precise enough. The better pattern is:
grep '1\.2\|1\.3' /root/one
Or even better, because more compact:
grep '1\.[23]' /root/one
You have to use ||
#!/bin/bash
echo "checking"
if grep -q 1.2 /root/one || grep -q 1.3 /root/one; then
echo " vetri Your NAC version"
fi
Single | operator is called pipe. It will pass the output of the command before | to the command after |.
It is better to join these these greps with | (OR operator):
grep '1.2\|1.3'
or
grep -E '1.2|1.3'
I guess the easier way to do this is to create a variable to check the count of occurrences:
#!/bin/bash
echo "checking"
CHECK=`egrep -c '1\.(2|3)' /root/one`
if [ "$CHECK" -gt 0 ]; then
echo "vetri Your NAC version"
fi

Bash Script : Unwanted Output

I have this simple bash script:
I run ns simulator on each file passed in argument where last argument is some text string to search for.
#!/bin/bash
nsloc="/home/ashish/ns-allinone-2.35/ns-2.35/ns"
temp="temp12345ashish.temp"
j=1
for file in "$#"
do
if [ $j -lt $# ]
then
let j=$j+1
`$nsloc $file > $temp 2>&1`
if grep -l ${BASH_ARGV[0]} $temp
then
echo "$file Successful"
fi
fi
done
I expected:
file1.tcl Successful
I am getting:
temp12345ashish.temp
file1.tcl Successful
When i run the simulator command myself on the terminal i do not get the file name to which output is directed.
I am not getting from where this first line of output is getting printed.
Please explain it.
Thanks in advance.
See man grep, and see specifically the explanation of the -l option.
In your script (above), you are using -l, so grep is telling you (as instructed) the filename where the match occurred.
If you don't want to see the filename, don't use -l, or use -q with it also. Eg:
grep -ql ${BASH_ARGV[0]} $temp
Just silence the grep:
if grep -l ${BASH_ARGV[0]} $temp &> /dev/null

Find and highlight text in linux command line

I am looking for a linux command that searches a string in a text file,
and highlights (colors) it on every occurence in the file, WITHOUT omitting text lines (like grep does).
I wrote this handy little script. It could probably be expanded to handle args better
#!/bin/bash
if [ "$1" == "" ]; then
echo "Usage: hl PATTERN [FILE]..."
elif [ "$2" == "" ]; then
grep -E --color "$1|$" /dev/stdin
else
grep -E --color "$1|$" $2
fi
it's useful for stuff like highlighting users running processes:
ps -ef | hl "alice|bob"
Try
tail -f yourfile.log | egrep --color 'DEBUG|'
where DEBUG is the text you want to highlight.
command | grep -iz -e "keyword1" -e "keyword2" (ignore -e switch if just searching for a single word, -i for ignore case, -z for treating as a single file)
Alternatively,while reading files
grep -iz -e "keyword1" -e "keyword2" 'filename'
OR
command | grep -A 99999 -B 99999 -i -e "keyword1" "keyword2" (ignore -e switch if just searching for a single word, -i for ignore case,-A and -B for no of lines before/after the keyword to be displayed)
Alternatively,while reading files
grep -A 99999 -B 99999 -i -e "keyword1" "keyword2" 'filename'
command ack with --passthru switch:
ack --passthru pattern path/to/file
I take it you meant "without omitting text lines" (instead of emitting)...
I know of no such command, but you can use a script such as this (this one is a simple solution that takes the filename (without spaces) as the first argument and the search string (also without spaces) as the second):
#!/usr/bin/env bash
ifs_store=$IFS;
IFS=$'\n';
for line in $(cat $1);
do if [ $(echo $line | grep -c $2) -eq 0 ]; then
echo $line;
else
echo $line | grep --color=always $2;
fi
done
IFS=$ifs_store
save as, for instance colorcat.sh, set permissions appropriately (to be able to execute it) and call it as
colorcat.sh filename searchstring
I had a requirement like this recently and hacked up a small program to do exactly this. Link
Usage: ./highlight test.txt '^foo' 'bar$'
Note that this is very rough, but could be made into a general tool with some polishing.
Using dwdiff, output differences with colors and line numbers.
echo "Hello world # $(date)" > file1.txt
echo "Hello world # $(date)" > file2.txt
dwdiff -c -C 0 -L file1.txt file2.txt

Bash shell `if` command returns something `then` do something

I am trying to do an if/then statement, where if there is non-empty output from a ls | grep something command then I want to execute some statements. I am do not know the syntax I should be using. I have tried several variations of this:
if [[ `ls | grep log ` ]]; then echo "there are files of type log";
Well, that's close, but you need to finish the if with fi.
Also, if just runs a command and executes the conditional code if the command succeeds (exits with status code 0), which grep does only if it finds at least one match. So you don't need to check the output:
if ls | grep -q log; then echo "there are files of type log"; fi
If you're on a system with an older or non-GNU version of grep that doesn't support the -q ("quiet") option, you can achieve the same result by redirecting its output to /dev/null:
if ls | grep log >/dev/null; then echo "there are files of type log"; fi
But since ls also returns nonzero if it doesn't find a specified file, you can do the same thing without the grep at all, as in D.Shawley's answer:
if ls *log* >&/dev/null; then echo "there are files of type log"; fi
You also can do it using only the shell, without even ls, though it's a bit wordier:
for f in *log*; do
# even if there are no matching files, the body of this loop will run once
# with $f set to the literal string "*log*", so make sure there's really
# a file there:
if [ -e "$f" ]; then
echo "there are files of type log"
break
fi
done
As long as you're using bash specifically, you can set the nullglob option to simplify that somewhat:
shopt -s nullglob
for f in *log*; do
echo "There are files of type log"
break
done
Or without if; then; fi:
ls | grep -q log && echo 'there are files of type log'
Or even:
ls *log* &>/dev/null && echo 'there are files of type log'
The if built-in executes a shell command and selects the block based on the return value of the command. ls returns a distinct status code if it does not find the requested files so there is no need for the grep part. The [[ utility is actually a built-in command from bash, IIRC, that performs arithmetic operations. I could be wrong on that part since I rarely stray far from Bourne shell syntax.
Anyway, if you put all of this together, then you end up with the following command:
if ls *log* > /dev/null 2>&1
then
echo "there are files of type log"
fi

Resources