Linux grep command - linux

Can I use grep command to look for all the lines in a file that have"abc" in them, but exclude the lines that end in say "xyz"?
Eg grep 'abc' fileName (some way to exclude all lines ending in "xyz")

Try this:
hzhang#dell-work ~ $ cat sample.csv
abc, xyz
abc,1
abc,2
abc,3,xyz
hzhang#dell-work ~ $ grep abc sample.csv |grep -v "xyz$"
abc,1
abc,2
The explanation of -v:
-v, --invert-match
Invert the sense of matching, to select non-matching lines. (-v is specified by POSIX.)
If you can use awk, just check the patterns:
hzhang#dell-work ~ $ awk '/abc/ && !/xyz$/' sample.csv
abc,1
abc,2

awk fit's pretty good for such cases:
awk '/abc/ && !/xyz$/' input
use awk! :)

Use two grep commands piped together. The first matches abc, the second removes the ones that end with xyz.
grep abc filename | grep -v 'xyz$'

Related

How to search exact phrase from a file which consist of set of phrase with hyphen

I have the file, which consists of a couple of phrases as follows. I would like to grep the exact match from out of them.
file.txt
abc
abc-def
xyz
xyz-pqr
pqrs
If I search "abc" I need to return only abc.
or
if I search "abc-def" i need to return only "abc-def"
preferd output
$grep -w "abc" file.txt
abc
or
$grep -w "abc-def" file.txt
abc-def
the below method is not working for the hyphens
$grep -w abc file.txt
With your given data/file you can use the -x flag.
grep -x abc file.txt
grep -x abc-def file.txt
-x, --line-regexp force PATTERN to match only whole lines
The -x flag is defined/required by POSIX grep(1)
In order to match an entire line you need to match the start and end of the line:
grep '^abc$' file.txt
grep '^abc-def$' file.txt
You can use awk this way:
awk -v w="abc" '$1==w' file.txt
abc
Or,
awk '$1==w' w="abc" file.txt
With the == operator, it only returns exact string matches. We are setting what to match with w="abc" either with the -v switch or through stdin.

Capturing string between 2 specific letters/words using shell scripting

I am trying to capture the string between 2 specific letters/words using sed/awk. This is what I am trying to do:
The input is a file test.log containing
Owner: CN=abc.samplecerrt.com,o=IN,DC=com
Owner: CN=abc1.samplecerrt.com,o=IN,DC=com
I want to extract only "CN=abc.samplecerrt.com"
I tried
sed 's/.*CN=\(.*\),.*/\1/p' test.log >> result.log
But this returns "abc.samplecerrt.com,o=IN,DC=com"
How do I go about this?
test file:
$ cat logs.txt
CN=abc.samplecerrt.com,o=IN,DC=com Owner: CN=abc1.samplecerrt.com,o=IN,DC=com
command and output:
$ grep -oP 'CN=(?:(?!CN=).)*?.com' logs.txt
CN=abc.samplecerrt.com
CN=abc1.samplecerrt.com
This might work for you (GNU sed):
sed -n 's/.*\(CN=[^,]*\).*/\1/p' file
Or:
sed 's/.*\(CN=[^,]*\).*/\1/p;d' file
The first turns off implicit printing -n so as to act like grep.
Matches and captures the string CN= followed by zero or more non-comma characters and prints the captured group \1 if a match is made.
The second solution is much the same except it deletes all lines and only prints the captured group as above.
With awk you can get the field where is the string you need. For it, you can set FS=:|, Now if you run
awk -v FS=":|," '{print $2}' file
CN=abc.samplecerrt.com
CN=abc1.samplecerrt.com
you get the field. But you only want one, so
awk -v FS=":|," '$2 !~ /abc1/ {print $2}' file
CN=abc.samplecerrt.com

Search A and replace B in A|B in shell scripting/SED/AWK

I have a text file with layout as:
tableName1|counterVariable1
tableName2|counterVariable2
I want to replace the counterVariable1 with some other variable say counterVariableNew.
How can I accomplish this?
I have tried various SED/AWK approaches, closest one is mentioned below:
cat $fileName | grep -w $tableName | sed -i 's/$tableName\|counterVariable/$tableName\|counterVariableNew'
But all the 3 commands are not merging properly, please help!
Your script is an example of [ useless use of cat ]. But the key point here is to escape the pipe delimiter which has a special meaning(it stands for OR) when used with awk FS. So below script should do
# cat 42000479
tableName1|counterVariable1
tableName2|counterVariable2
tableName3|counterVariable2
# awk -F\| '$1=="tableName2"{$2="counterVariableNew"}1' 42000479
tableName1|counterVariable1
tableName2 counterVariableNew
tableName3|counterVariable2
An alternate way of doing the same stuff is below
# awk -v FS='|' '$1=="tableName2"{$2="counterVariableNew"}1' 42000479
Stuff inside the single quote will not be expanded.
awk -F'|' -v OFS='|' '/tableName1/ {$2="counterVariableNew"}1' file
tableName1|counterVariableNew
tableName2|counterVariable2
This will search for A (tableName1) and replace B (counterVariable1) to counterVariableNew.
Or by using sed :
sed -r '/tableName1/ s/(^.*\|)(.*)/\1counterVariableNew/g' file
tableName1|counterVariableNew
tableName2|counterVariable2
For word bounded search: Enclose the pattern inside \< and \> .
sed -r '/\<tableName1\>/ s/(^.*\|)(.*)/\1counterVariableNew/g' file
awk -F'|' -v OFS='|' '/\<tableName1\>/ {$2="counterVariableNew"}1' file

grep exclude multiple strings

I am trying to see a log file using tail -f and want to exclude all lines containing the following strings:
Nopaging the limit is and keyword to remove is
I am able to exclude one string like this:
tail -f admin.log|grep -v "Nopaging the limit is"
But how do I exclude lines containing either of string1 or string2?
Filtering out multiple lines with grep:
Put these lines in filename.txt to test:
abc
def
ghi
jkl
grep command using -E flag with a pipe between tokens in a string:
grep -Ev 'def|jkl' filename.txt
prints:
abc
ghi
egrep using -v flag with pipe between tokens surrounded by parens:
egrep -v '(def|jkl)' filename.txt
prints:
abc
ghi
Or if stacking -e flags through grep parameters is okay (credit -> #Frizlab):
grep -Fv -e def -e jkl filename.txt
prints:
abc
ghi
grep -Fv -e 'Nopaging the limit is' -e 'keyword to remove is'
-F matches by literal strings (instead of regex)
-v inverts the match
-e allows for multiple search patterns (all literal and inverted)
Another option is to create a exclude list, this is particulary usefull when you have a long list of things to exclude.
vi /root/scripts/exclude_list.txt
Now add what you would like to exclude
Nopaging the limit is
keyword to remove is
Now use grep to remove lines from your file log file and view information not excluded.
grep -v -f /root/scripts/exclude_list.txt /var/log/admin.log
egrep -v "Nopaging the limit is|keyword to remove is"
tail -f admin.log|grep -v -E '(Nopaging the limit is|keyword to remove is)'
You can use regular grep like this:
tail -f admin.log | grep -v "Nopaging the limit is\|keyword to remove is"
The greps can be chained. For example:
tail -f admin.log | grep -v "Nopaging the limit is" | grep -v "keyword to remove is"
If you want to use regex:
grep -Ev -e "^1" -e '^lt' -e 'John'

Linux, Print all lines in a file, NOT starting with

I would like to print the contents of a file, but all lines starting with # I want to ignore. I was trying some stuff with grep and awk, but it kept printing the whole file, or just printed the lines starting with #. I you could give me a push in the right way, or a grep/awk command that would print anyline in the file that does not start with #.
Use the -v option of grep to negate the condition:
grep -v '^#' file
You can use the ! operator:
awk '!/^ *#/ { print; }'
This negates the result of the match. I also included lines that start with spaces and then #, but you can tailor the regex how you like.
You could use grep to exclude all lines that begin with # using the -v option
grep -v '^#' filename
If you're a fan of sed:
sed '/^#/d' filename
This would also leave out lines with whitespace before the # :
awk '$1!~/^#/' file
or
grep -v '^[[:blank:]]*#' file
Here is the grep PCRE way,
grep -P '^(?!#)' file

Resources