The following CLI one-liner prints all the lines between the lines containing PATTERN1 and PATTERN2 (including the lines with these two patterns) in a file, FILENAME:
sed -n '/PATTERN1/,/PATTERN2/p' FILENAME
17 Monday Dec 2012
04 Sunday Nov 2012
Posted in vim
1. Show all the lines that match a pattern, say PATTERN
:g/PATTERN
Use “g!” or “v” for negative matching. For example, to show all the lines that DO NOT match the pattern, PATTERN, use
:g!/PATTERN
2. Delete all the lines that contain the pattern, PATTERN
:g/PATTERN/d
Again, g! or v may be used for negative matching.
Application: You may use any of the following two commands to delete all the blank lines (including lines containing only whitespaces) from a file
:g/^\s*$/d
:v/\S/d
Reference: Vim Wiki.
26 Saturday Sep 2009
Posted in awk
Print columns 1, 5 and then 2, put a colon, and then print column 10 of a line that matches pattern from the file columns.txt:
$ awk '/pattern/ {print $1, $5, $2, ": ", $10}' columns.txt
.
Protecting the special meaning of the single quotes and curly braces
I came across this situation when I was trying to watch the above command as well as two other commands (say, command1 and command2) at the same time. The correct way to do that is by properly protecting the meaning of the special characters in the above awk invocation:
$ watch -d -n 20 "command1; command2; awk '"'/pattern/ {print $1, $5, $2, ": ", $10}'"' columns.txt".
N.B. The “-d”flag highlights the changes, whereas the “-n 20” flag causes the above to watch every 20 seconds.
Just for the heck of it, let me put the full command that I was actually using:
$ watch -d -n 20 "ps aux | grep -i columbus | grep -v grep && echo; tail WORK/ciudgsm && echo && grep bond output.log | tail -13 && echo && awk '"'/state # 1/ {print $3,$4,$5,": ", $10}'"' output.log && echo; awk '"'/state # 2/ {print $3,$4,$5,": ", $10}'"' output.log && head curr_iter"
(suggestions for making the above shorter, other than by aliasing, are most welcome!).
Reference: here.
26 Saturday Sep 2009
I always get confused about various flavors of grep. Here’s a summary to shine some light: (man grep to know more!)
egrep or grep -E (in linux only) is extended grep where additional regular expression metacharacters have been added like +, ?, | and ()fgrep or grep -F (in linux only) is fixed or fast grep and behaves as grep but does not recognize any regular expression metacharacters as being special.25 Friday Sep 2009
For grepping line-by-line in a file filename, I often find these very useful
Match pattern1 OR pattern2 in the same line:
$ grep -E 'pattern1|pattern2' filename
Match pattern1 AND pattern2 in the same line:
$ grep -E 'pattern1.*pattern2' filename
The above command searches for pattern1 followed by pattern2. If the order does not matter or you want to search them in either order, then use the follwoing
$ grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename
The pipe enables the OR search which we saw earlier. Another option for this situation (i.e., AND search when the order is not important):
$ grep -E 'pattern1' filename | grep -E 'pattern2'
which basically greps the STDOUT of the first grep.
Match pattern1 AND pattern2, but NOT pattern3 in the same line:
$ grep -E 'pattern1.*pattern2' filename | grep -Ev 'pattern3'
when the order of the first two patterns is important. When that order is NOT important:
$ grep -E 'pattern1' filename | grep -E 'pattern2' | grep -Ev 'pattern3'
Match pattern1 OR pattern2, but NOT pattern3 in the same line:
$ grep -E 'pattern1|pattern2' filename | grep -Ev 'pattern3'
N.B. (1) grep -E may be replaced by egrep. I used grep -E everywhere in this post assuming a general case of regular expressions as patterns. Lowercase -e is also used for regex, but this is more “basic” than -E which supports “extended” regex, e.g. regular expression metacharacters like +, ?, | and (). (2) The -v flag is for non-matching grep.