linux - how to work with 'while ..; do..; done' in bash -
this question has answer here:
- use shell iterate through file 2 answers
i having trouble using command in bash operation. following have:
cat namelist | while read line; awk '$1 == $line {print $0}' jan.txt; done
the namelist
unrepeated namelist each name on each line. , jan.txt file of information these:
ermartin pts/10 tue jan 19 09:49 - 10:15 (00:26) 171.66.208.139 sdou pts/6 tue jan 19 01:52 - 22:20 (9+20:27) 131.243.186.99 sdou pts/2 tue jan 19 01:20 - 22:20 (9+20:59) 131.243.186.99 phu pts/2 sat jan 16 12:21 - 15:13 (02:52) lbl-ipsec-7667.dhcp.lbl.gov phu pts/2 sat jan 16 10:07 - 12:01 (01:54) lbl-ipsec-7622.dhcp.lbl.gov sjames pts/5 fri jan 15 12:06 - 13:06 (01:00) lakshmi.lbl.gov ermartin pts/2 fri jan 15 08:36 - 12:43 (04:07) 171.66.208.134 ermartin pts/2 fri jan 15 08:31 - 08:36 (00:05) 171.66.208.134 camitche pts/4 thu jan 14 15:18 - 20:47 (05:28) 171.66.208.134 ermartin pts/2 thu jan 14 13:20 - 15:57 (02:36) 171.66.208.139 ermartin pts/2 thu jan 14 12:35 - 13:00 (00:25) 171.66.208.139 sjames pts/2 thu jan 14 06:17 - 06:27 (00:09) phys1.als.lbl.gov sjames pts/2 thu jan 14 06:17 - 06:17 (00:00) phys1.als.lbl.gov ermartin pts/0 wed jan 13 15:19 - 15:50 (00:31) 171.66.208.139 ermartin pts/0 wed jan 13 07:55 - 08:09 (00:13) c-24-130-14-154.hsd1.ca.comcast.net
i trying match names in namelist
file , operation each line of information in file when did $1 == $line
, says it's error. how make use of command properly?
is possible loop on months , print them title like:
[jan] sjames ...hours sdou ...hours [feb] sjames ...hours sdou ...hours
first, awk , shell not share variables. is, however, possible transfer shell variable awk variable using -v
option. following works , change code adding -v line="$line"
option:
cat namelist | while read line; awk -v line="$line" '$1 == line {print $0}' jan.txt; done
note awk references line
variable line
no dollar sign.
a possible replacement above pipeline is:
awk 'fnr==nr{a[$1]; next;} $1 in a' namelist jan.txt
here, associative array a
keeps track of names in namelist
, uses decide whether print lines in jan.txt.
if not going more processing of data (but gather opposite true), then, shellter suggests in comments, above replaced with:
grep -ff namelist jan.txt
if want calculate time used users in namelist, try:
$ awk -f'[ +:()]+' 'fnr==nr{a[$1]; next;} !($1 in a){next} nf==13{b[$1]+=$12+60*$11} nf==14{b[$1]+=$13+60*($12+24*$11)} end{for (n in b)print n,b[n]}' namelist jan.txt
as example, consider namelist:
$ cat namelist sdou phu
the calculated times are:
$ awk -f'[ +:()]+' 'fnr==nr{a[$1]; next;} !($1 in a){next} nf==13{b[$1]+=$12+60*$11} nf==14{b[$1]+=$13+60*($12+24*$11)} end{for (n in b)print n,b[n]}' namelist jan.txt phu 286 sdou 28406
for readability, may easier see same code spread on multiple lines:
awk -f'[ +:()]+' ' fnr==nr{ a[$1] next } !($1 in a){ next } nf==13{ b[$1]+=$12+60*$11 } nf==14{ b[$1]+=$13+60*($12+24*$11) } end{ (n in b) print n,b[n] } ' namelist jan.txt phu 286
to track usage user , month:
$ awk -f'[ +:()]+' 'fnr==nr{a[$1]; next;} !($1 in a){next} nf==13{b[$1"["$4"]"]+=$12+60*$11} nf==14{b[$1"["$4"]"]+=$13+60*($12+24*$11)} end{for (n in b)print n,b[n]}' namelist jan.txt phu[jan] 286 sdou[jan] 28406
Comments
Post a Comment