2013-02-26 40 views
0

1)解決問題後: How to translate 'system()' call to 'fork() + execl()' when dealing with awk command?'系統' 到 '叉+ execv' 與awk命令處理時

2)I遇到根據墨爾波墨涅的方法的另一個問題:

#define LOG_FILE_PATH "/tmp/logfile" 
system("awk -v FS=\"[][]\" -v BEGINTIME=\"$BEGINTIME\" -v ENDTIME=\"$ENDTIME\" '$2>=BEGINTIME && $2<=ENDTIME' "LOG_FILE_PATH); 

它的工作原理罰款,我得到我想要的。

3)翻譯成叉+ execl的版本:

sprintf(tmp1, "BEGINTIME=%s", getenv("BEGINTIME")); 
sprintf(tmp2, "ENDTIME=%s", getenv("ENDTIME")); 
sprintf(tmp3, "$2>=%s && $2<=%s", getenv("BEGINTIME"), getenv("ENDTIME")); 
execl("/usr/bin/awk", "awk", "-v", "FS=\"[][]\"", "-v", tmp1, "-v", tmp2, tmp3, LOG_FILE_PATH, (char *)0); 

它輸出什麼,爲什麼?

回答

2

因爲tmp 3應該包括字面文本BEGINTIMEENDTIME。嘗試:

sprintf(tmp3, "$2>=%s && $2<=%s", "BEGINTIME", "ENDTIME"); 

另外,你可能希望保留雙引號tmp1tmp2

sprintf(tmp1, "BEGINTIME=\"%s\"", getenv("BEGINTIME")); 

,你真的需要檢查環境變量的實際設置。

此外,您正在設置FS不正確。在system版本,awk得到論證FS=[][](它調用awk前殼去掉雙引號)。所以傳遞到execl的說法應該是"FS=[][]"

+0

我改成 ' sprintf(tmp3,「$ 2> =%s && $ 2 <=%s」,「BEGINTIME」,「ENDTIME」);' 但它也不起作用。 – dejunl 2013-02-26 11:51:12

+3

「不起作用」不是有用的診斷。 – 2013-02-26 11:52:55

+0

@dejunl我剛剛注意到你也在錯誤地設置FS。回答編輯。 – 2013-02-26 13:20:16

0

如果你是在Solaris上,然後在/ usr/bin中/ AWK是破舊的awk,其中許多其他問題不支持-v進行變量賦值。

而且,awk程序由一個引號字符分隔,所以我認爲你應該做這樣的事情:

sprintf(tmp3, "\'$2>=%s && $2<=%s\'", ...); 

,而不是這樣的:

sprintf(tmp3, "$2>=%s && $2<=%s", ...); 
+1

在shell中:'awk'$ 2> = k''將文字參數'$ 2> = k'傳遞給awk。 (Shell剝去單引號。)將單引號放入傳遞給'exec *'的字符串中不會去掉引號。如果你不去掉引號,'awk'會抱怨語法錯誤。換句話說,它就像從shell中調用'awk''\ $ 2> = k'「'一樣。 – 2013-02-26 13:14:56

+0

那麼OPs現有的代碼會導致shell獲得'awk「$ 2> = k」'或'awk $ 2> = k'?無論哪種方式,$ 2將是shell位置參數而不是輸入文件中的字段,對吧? – 2013-02-26 13:25:08

+1

在現有的代碼中,參數awk認爲沒有雙引號,但它確實有一個文字'$',所以'$ 2'指向該字段中的文件。使用'exec *',shell完全不在圖片中,所以'$ 2'不能引用位置參數。 – 2013-02-26 13:30:19