Tuesday, June 29, 2010

Exact match with UNIX grep and awk


Input file:

$ cat file.txt
1 172.17.4.1
2 172.17.4.5
3 172.17.4.8
4 172.27.4.19
5 172.24.4.12

Now:

$ grep '172.17.4.1' file.txt
1 172.17.4.1
4 172.17.4.19
5 172.17.4.12

Are you trying to grep exact '172.17.4.1' ?

From grep man pages:

-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.


$ grep -w '172.17.4.1' file.txt
1 172.17.4.1

Another alternative:

$ grep '\<172.17.4.1\>' file.txt
1 172.17.4.1

Normal awk match:

$ awk '$2 ~ /172.17.4.1/ {print $1}' file.txt
1
4
5

To make it exact match,
From gawk man pages

\y
matches the empty string at either the beginning or the end of a word.

So,

$ awk '$2 ~ /\y172.17.4.1\y/ {print $1}' file.txt
1

For exact match in awk, you can use this though

$ awk '$2=="172.17.4.1" {print $1}' file.txt

Related posts :

- Highlight match with color in UNIX grep command
- Print only matched string not line using UNIX grep
- Grep and print control characters in file - UNIX

Sunday, June 27, 2010

Insert text at top of file in UNIX

Purpose : Insert text at the top and bottom of a file in UNIX.

I had a lot of .in extension files in my current working directory.

One of them:

$ cat a.in
k|1|4|rty|3.4|67|1
k|2|4|rty|1.4|67|1
k|3|4|rty|3.7|62|2

Required: I had to insert two lines at the top of each files and a line at the bottom of each files.

e.g. After modification above file should look like this:

$ cat a.in
h1|t|4
h2|r|0
k|1|4|rty|3.4|67|1
k|2|4|rty|1.4|67|1
k|3|4|rty|3.7|62|2
#End

Solutions:

Unix 'Sed' utility is suitable for adding/appending, changing or inserting lines to files. You can refer one of my earlier post on this.

The bash script using 'sed':

#!/bin/sh

FILES=$(echo *.in)

for file in $FILES
do
echo "Modifying file : $file"

sed '1i\
h1|t|4' $file | sed '2i\
h2|r|0' | sed '$a\
#End' > $file.tmp

mv $file.tmp $file
done

With newer version of 'sed', the use of temporary files in the above bash script can be avoided by using '-i' option. Please refer example

-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)

A plain bash script without using 'sed' utility would be something like this:

for file in $(ls *.in)
do
echo "Modifying file : $file"
echo "h1|t|4" >> $file.tmp
echo "h2|r|0" >> $file.tmp
cat $file >> $file.tmp
echo "#End" >> $file.tmp
mv $file.tmp $file
done

Awk way of inserting a line of text in any line number (say insert text 'first line' as line number 1 of file.txt)

$ awk 'NR==1{print "first line"}1' file.txt


A related post:

- UNIX - add text in the middle of a file using awk in bash

© Jadu Saikia http://unstableme.blogspot.com