How do i use grep command to filter the ip address.
3267 3 77.80.177.0/24 00:00:00:00:00:00 100011 0 0 0 0 y
3289 1 177.77.1.0/24 00:00:00:00:00:00 100010 0 0 0 0 y
I want to filter only the entries starting with 177. which appears on column 3.
There is no uniform spacing between columns.
sorry I'm not comfortable using grep . I tried to google and got some examples but did not work the way that I intend do.
Thanks,
It might be easier with awk:
$ awk '$3 ~ /^177/' file
3289 1 177.77.1.0/24 00:00:00:00:00:00 100010 0 0 0 0 y
'$3 ~ /^177/' means: in case the 3rd field contains an string that starts with 177, then print it.
To have it done with grep:
$ grep -E "^\w+\s+\w+\s+177" file
3289 1 177.77.1.0/24 00:00:00:00:00:00 100010 0 0 0 0 y
-E "^\w+\s+\w+\s+177" file means: look for strings with this pattern: start of line, word, spaces, word, spaces, 177.
grep " 177\." File
That should do it
I would prefer awk over this but here are both solution:
With grep:
grep -vE '\s*177\.([0-9]+\.){2}[0-9]\/[0-9]+\s*' inputFile
With awk:
awk '$3!~/^177/' inputFile
Based on your sample, here's another one:
$ grep -o '[^.0-9]177.*/[0-9]{2}'
Results in (note the leading space):
177.77.1.0/24
Related
I am new to linux and I am experimenting with basic terminal commands. I found out that I can list all users using compgen -u but what if I only want to display the bottom line outputs ?
Ok lets say the output of compgen -u goes like this:
extra
extra
extra
extra
extra
extra
extra
extra
extra
John
William
Kate
Harold
I can only use grep to find a single text (ex. compgen -u | grep John). But what if I want to use grep to display John as well as all the remaining entries after it ?
sed or awk solution would be easier, but if you can only use grep, then the option --after-context (or -A) might do:
grep -A 5 John file
The drawback is that you need to know the number of lines to display after the matching (or use an arbitrary big number for the rest of the file).
compgen -u | grep -A$(compgen -u| wc -l) John
Explanation:
From man grep
-A NUM, --after-context=NUM
Print NUM lines of trailing context after matching lines. Places a line containing a group separator (described under --group-separator) between
contiguous groups of matches.
grep -A -- print number of rows after pattern
$() -- Execute unix command
compgen -u| wc -l --> Get total number of rows of output of command.
You can use the following one-liner :
n=$( compgen -u | grep -n John | head -1 | cut -d ":" -f 1 ) && compgen -u | tail -n +$n
This finds out the line number for first occurrence of John, and prints everything starting that line.
How can I do an exact match using grep -v?
For example: the following command
for i in 0 0.3 a; do echo $i | grep -v "0"; done
returns a. But I want it to return 0.3 a.
Using
grep -v "0\b"
is not working
for i in 0 0.3 a; do echo $i | grep -v "^0$"; done
You need to match the start and end of the string with ^ and $
So, we say "match the beginning of a line, the char 0 and then the end of the line.
$ for i in 0 0.3 a; do echo $i | grep -v "^0$"; done
0.3
a
The safest way for single-column entries is using awk. Normally, I would use grep with the -w flag, but since you want to exactly match an integer that could be part of a float, it is a bit more tricky. The <dot>-character makes it hard to use any of
grep -vw 0
grep -v '\b0\b'
grep -v '\<0\>'
The proposed solution also will only work on perfect lines, what if you have a lost space in front or after your zero. The line will fail. So the safest would be:
single column file:
awk '($1!="0")' file
multi-word file: (adopt the variable FS to fit your needs)
awk '{for(i=1;i<=NF;++i) if($i == "0") next}1' file
I have two text files containing one column each, for example -
File_A File_B
1 1
2 2
3 8
If I do grep -f File_A File_B > File_C, I get File_C containing 1 and 2. I want to know how to use grep -v on two files so that I can get the non-matching values, 3 and 8 in the above example.
Thanks.
You can also use comm if it allows empty output delimiter
$ # -3 means suppress lines common to both input files
$ # by default, tab character appears before lines from second file
$ comm -3 f1 f2
3
8
$ # change it to empty string
$ comm -3 --output-delimiter='' f1 f2
3
8
Note: comm requires sorted input, so use comm -3 --output-delimiter='' <(sort f1) <(sort f2) if they are not already sorted
You can also pass common lines got from grep as input to grep -v. Tested with GNU grep, some version might not support all these options
$ grep -Fxf f1 f2 | grep -hxvFf- f1 f2
3
8
-F option to match strings literally, not as regex
-x option to match whole lines only
-h to suppress file name prefix
f- to accept stdin instead of file input
awk 'NR==FNR{a[$0]=$0;next} !($0 in a) {print a[(FNR)], $0}' f1 f2
3 8
To Understand the meaning of NR and FNR check below output of their print.
awk '{print NR,FNR}' f1 f2
1 1
2 2
3 3
4 4
5 1
6 2
7 3
8 4
Condition NR==FNR is used to extract the data from first file as both NR and FNR would be same for first file only.
With GNU diff command (to compare files line by line):
diff --suppress-common-lines -y f1 f2 | column -t
The output (left column contain lines from f1, right column - from f2):
3 | 8
-y, --side-by-side - output in two columns
my first post here.
In summary: I have a netstat output, using "netstat -an" command in Windows, and I would like to get the top number of one of the columns.
The output of netstat is something like this:
TCP 10.45.43.232:50387 10.42.48.61:902 ESTABLISHED
TCP 10.45.43.232:50559 46.228.47.115:443 CLOSE_WAIT
TCP 10.45.43.232:52501 10.48.48.128:3389 ESTABLISHED
TCP 10.45.43.232:58000 10.46.48.243:63713 ESTABLISHED
The result I want is:
58000
That number is the biggest value on the second column, after the ":" character
So, in essence, I want a grep (and/or sed, awk, etc) which can search through a file, only look in the first 25 characters of each line, and get the highest number after a ":" character.
Tell me if you need more information, thanks in advance!
This can be an approach:
netstat ... | sort -t':' -nrk2 | awk -F"[ :]" '{print $8; exit}'
By pieces:
Sort it based on : as delimiter and taking second column into account:
$ netstat ... | sort -t':' -nrk2
TCP 10.45.43.232:58000 10.46.48.243:63713 ESTABLISHED
TCP 10.45.43.232:52501 10.48.48.128:3389 ESTABLISHED
TCP 10.45.43.232:50559 46.228.47.115:443 CLOSE_WAIT
TCP 10.45.43.232:50387 10.42.48.61:902 ESTABLISHED
Print the biggest:
$ netstat ... | sort -t':' -nrk2 | awk -F"[ :]" '{print $8; exit}'
58000
Or better, using Mark Setchell's approach to fetch the last item:
$ netstat ... | sort -t':' -nrk2 | awk '{sub(/.*:/,"",$2); print $2; exit}'
58000
if the output has leading space/tabs:
netstat...|awk -F':|\\s*' '{p=$4>p?$4:p}END{print p}'
if there is no leading spaces:
netstat ..| awk -F':|\\s*' '{p=$3>p?$3:p}END{print p}'
I would go with this:
netstat -an | awk '{sub(/.*:/,"",$2); if($2>max)max=$2} END{print max}'
The sub() part strips all characters up to and including a colon, off the second field thereby extracting the port. If that is greater than max, max is updated. At the end, max is printed.
Here is yet another way using GNU awk:
netstat ... | awk '{split($2,tmp,/:/); a[tmp[2]]++}END{n=asorti(a);print a[n]}'
We split the second field of second column (delimited by :) in a tmp array
We populate the values as keys in array a.
In the END we use GNU awk asorti function which sorts the keys and print the highest.
You can also do it with coreutils alone:
netstat ... | cut -d: -f2 | cut -d' ' -f1 | sort -nr | head -n1
Output:
58000
I am trying hard to get the output as I Like.
Current Output:
###Server1###
2
###Server2###
0
###Server3###
5
###Server4###
0
Required Output:
###Server1###
2
###Server3###
5
All I am looking is to grep and ignore any line and the previous line that containts 0 (zero) in any place of the line. I am using bash shell.
This is a possible approach:
$ grep -B 1 "^\s*[1-9]$" file
###Server1###
2
--
###Server3###
5
To get rid of the group separator, we can also do:
$ grep --no-group-separator -B 1 "^\s*[1-9]$" file
###Server1###
2
###Server3###
5
Explanation
Instead of using grep -v to find the inverse, I think it is easier to look for the lines having a single digit value not being 0. This is done with the "^\s*[1-9]$" expression, that allows spaces before the digit.
With -B 1 we make it print also the line before the matched one.
Code for GNU sed:
sed '$!N;/\s*\b0\b\s*/d' file
$ sed '$!N;/\s*\b0\b\s*/d' file
###Server1###
2
###Server3###
5