2011-12-28 43 views
1

下面的代碼工作取得的a狀態值,如果它的啓用,d如果禁用,n如果不存在,從文件如下:這在匹配中是否正確?

# Check whether the service entry exists and whether it is enabled or disabled 
# Status value 'a' states that the service is uncommented in /etc/inetd.conf. 
# Value 'd' states that the service is commented, and value 'n' specifies 
# that the service entry doesnt exist in the configuration file. 
status=`awk -v serv=$1 -v proto=$2 -v exist="n" ' 
     BEGIN { 
     format=sprintf("^[\t ]*%s.*%s",serv,proto); 
     comformat=sprintf("^[\t ]*#[\t ]*%s.*%s",serv,proto); 
     } 
     { 
     if(match($0,format)) 
     { 
       exist="a"; 
     } 
     else if(match($0,comformat)) 
     { 
       exist="d"; 
     } 
     } 
     END { 
     printf("%s",exist) 
     }' $INETD` 

從以下文件:

ftp  stream tcp6 nowait root /usr/sbin/ftpd   ftpd 
telnet stream tcp6 nowait root /usr/sbin/telnetd  telnetd -a 
shell stream tcp6 nowait root /usr/sbin/rshd   rshd 
#kshell stream tcp  nowait root /usr/sbin/krshd  krshd 
login stream tcp6 nowait root /usr/sbin/rlogind  rlogind 
#klogin stream tcp  nowait root /usr/sbin/krlogind  krlogind 

注意:$1 =文件中的第1列和$2 =文件中的第3列。

所以我關心的是如果上面的搜索使用以下格式足夠好?或者是有任何其它更好的正則表達式:

format=sprintf("^[\t ]*%s.*%s",serv,proto); 
comformat=sprintf("^[\t ]*#[\t ]*%s.*%s",serv,proto); 
+0

呦如果你有兩個名爲「service」和「service2」的服務,你將會遇到問題:你的正則表達式會匹配這兩個服務。 – fge 2011-12-28 12:12:51

+0

什麼是替代方案?相反,正確的方法來做到這一點? – footy 2011-12-28 12:33:15

+0

嗯,我不知道awk,但是你已經把它分開了。如果我是你,我會用「$ service」或「#$ service」檢查第一個字段是否相等。 – fge 2011-12-28 12:39:33

回答

1

根據我明白這個問題的可能工作 -

status=$(awk -v serv="$1" -v proto="$2" ' 
$1==serv && $3==proto {val="a";exit} 
$1=="#"serv && $3==proto {val="d";exit} 
END{if ((val=="a") || (val=="d")) print val; else print "n"}' $INETD) 

測試:基於手動傳遞的價值和使用下面的內容文件

[jaypal:~/Temp] cat f1 
ftp  stream tcp6 nowait root /usr/sbin/ftpd   ftpd 
telnet stream tcp6 nowait root /usr/sbin/telnetd  telnetd -a 
shell stream tcp6 nowait root /usr/sbin/rshd   rshd 
#kshell stream tcp  nowait root /usr/sbin/krshd  krshd 
login stream tcp6 nowait root /usr/sbin/rlogind  rlogind 
#klogin stream tcp  nowait root /usr/sbin/krlogind  krlogind 

[jaypal:~/Temp] awk -v serv="kshell" -v proto="tcp" ' # kshell exists but is commented 
$1==serv && $3==proto {val="a";exit} 
$1=="#"serv && $3==proto {val="d";exit} 
END{if ((val=="a") || (val=="d")) print val; else print "n"}' f1 
d 
[jaypal:~/Temp] awk -v serv="ftp" -v proto="tcp6" ' # tcp6 proto exits 
$1==serv && $3==proto {val="a";exit} 
$1=="#"serv && $3==proto {val="d";exit} 
END{if ((val=="a") || (val=="d")) print val; else print "n"}' f1 
a 
[jaypal:~/Temp] awk -v serv="ftp" -v proto="tcp" ' # tcp proto does not exist 
$1==serv && $3==proto {val="a";exit} 
$1=="#"serv && $3==proto {val="d";exit} 
END{if ((val=="a") || (val=="d")) print val; else print "n"}' f1 
n 
1

我想每個字符串後面添加一個空格,以避免@fge看到的問題。尤其是,如果沒有它,如果文件中包含「tcp6」,則會匹配「tcp」。

format=sprintf("^[\t ]*%s[\t ].*%s[\t ]",serv,proto); 
comformat=sprintf("^[\t ]*#[\t ]*%s[\t ].*%s[\t ]",serv,proto); 

使用大BEGIN塊不是很地道AWK但它可能與模式從外面一樣,未來的解決方案。

如果您AWK實現支持POSIX正則表達式,你也可以使用 '[:空間:]' 類來匹配空格的更扭結(= '[\ t \ r \ n符\ v \ F]')