Monday, June 20, 2011

Filter line using Awk split function


Input file "file.txt" has data in the following format:
$ cat file.txt
232323 90 /T/1382/8558/365p/133 100 234 679
S/1234 90 /N/1389/5000/365s/5000 800 134 679
792363 80 /T/1381/9858/365q/133 100 234 779
136383 90 /K/1382/5000/365p/5000 500 934 979
136383 90 /T/1382/5000/279p/9000 100 134 601

Required output: From the above file print only the lines whose 3rd field has the value "5000" as the 4th field (separated by the delimiter "/") in it. i.e. required output:
S/1234 90 /N/1389/5000/365s/5000 800 134 679
136383 90 /K/1382/5000/365p/5000 500 934 979
136383 90 /T/1382/5000/279p/9000 100 134 601

Using awk:
$ awk '{
split($3,arr,"/")
if(arr[4] == 5000) {
print $0
}
}' file.txt

The awk function split(s,a,sep) splits a string "s" into an awk array "a" using the delimiter "sep".

A simple UNIX bash script to solve this:
$ while read line
do
thirdf=$(echo "$line" | awk '{print $3}')
fourthf=$(echo "$thirdf" | awk -F "/" '{print $4}')
[ "$fourthf" -eq 5000 ] && echo $line
done < file.txt

Related posts:
- Add prefix to lines in a file using awk and bash
- Replace n-th occurrence of pattern in a file using Awk

3 comments:

Derek Evan Schrock said...

Complete bash solution:

while read _ _ three _; do [ "$( IFS='/' read _ _ _ forth _ <<< "${three}"; echo $forth )" -eq 5000 ] && echo $forth ; done

Naveen said...

Dear Jadu,

pls help ..

ls -l /notes/*/*.id|awk '{print $3}'
lotus01
lotus02
lotus03
lotus04
lotus05
lotus06

I have the above output , I want to grep server based on the above value.

ps -ef|grep lotus01/02/03/04/05/06|grep server

for i in `ls -l /notes/*/*.id|awk '{print $3}`;`ps -ef|grep $i|grep server`;done;
bash: syntax error near unexpected token ``ps -ef|grep $i|grep server`'

"ps -ef|grep $variable|grep server"

Thanks for your help
Naveen

Unknown said...

## bash based
peco() {
# echo without its idiosyncrasies
while :; do
case $# in
0) return;;
1) :;;
*) printf '%s ' "${@:1:$#-1}";;
esac
break
done
printf '%s\n' "${@:$#}"
}
while IFS= read -r Line; do
case $(read -r _ _ third _ <<< "$Line";IFS="/" read -r _ _ _ forth _ <<< "$third";peco "$forth") in
"5000") peco "$Line";;
esac
done < file.txt


# Sed based
sed -e '
h
s|[ ][ ]*|\n|2;s|.*\n||
s|/|\n|3;\|\n5000/|!d;g

' file.txt

# Perl
perl -wMstrict -lane 'print if 5000 == (split m{/}, $F[2])[3]' file.txt

© Jadu Saikia www.UNIXCL.com