2010-10-26 103 views
2

我已經這個傳遞輸出從一個命令作爲參數傳遞給另一個

for i in `ls -1 access.log*`; do tail $i |awk {'print $4'} |cut -d: -f 1 |grep - $i > $i.output; done 

LS會給的access.log,access.log.1,access.log.2等
會給我的每個文件的最後一行,它看起來像:192.168.1.23 - - [08/Oct/2010:14:05:04 +0300]等等,等等等等
AWK +切將提取的日期(08月/ 10月/ 2010 - 每個access.log的,但不同的),這將允許我grep,並將輸出重定向到單獨的文件。

但我似乎無法將awk + ​​cut的輸出傳遞給grep。

所有這一切的原因是這些訪問日誌包括具有多個日期的行(06/10月,07/10月,08/10月),我只需要最近日期的行。

我該如何做到這一點?

謝謝。

+0

你可以張貼一些示例輸入和預期的輸出? – 2010-10-26 11:29:59

+1

一個問題是,您爲每個access.log保留覆蓋相同的輸出。請注意,您也可以使用多個尾部文件。 – Tomas 2010-10-26 11:31:44

+0

大聲笑..你是對的,不知道我是如何忽略這個事實的。讓我想一想,所以我可以想出一個解決方法。 – w00t 2010-10-26 11:35:48

回答

1

作爲旁註,tail顯示最後10行。

一個可能的解決方案是grep這樣:

for i in `ls -lf access.log*`; do grep $(tail $i |awk {'print $4'} |cut -d: -f 1| sed 's/\[/\\[/') $i > $i.output; done 
+0

我不太在乎這方面。我可以使用tail -n 1. – w00t 2010-10-26 12:22:54

+0

@mouviciel - 我已經完全按照你寫的那樣嘗試過了,但是它給了grep:無與倫比的[或[^ – w00t 2010-10-26 12:44:49

+0

我看,'['對'grep'有特殊含義。我編輯我的答案。 – mouviciel 2010-10-26 12:51:27

0

嗯... 使用xargs或反引號。

man xargs 

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html,第3.4.5節。命令替換

+0

我看不出xargs如何幫助我。它需要知道所有先前命令的輸出是什麼,然後將其作爲模式傳遞給grep。它不會是'command | xargs grep 123 file.txt',但它會是'command | xargs grep -pattern-from-command-file.txt' – w00t 2010-10-26 12:40:35

1

你爲什麼不把它分解成步驟?

for file in *access.log 
do 
    what=$(tail "$i" |awk {'print $4'} |cut -d: -f 1) 
    grep "$what" "$file" >> output 
done 
+0

這也會在每次迭代中覆蓋'output'。 – 2010-10-26 11:37:31

+0

我想我可以分解它,但想從CLI運行它。總之,我不止一次需要使用這樣的功能,所以我試圖爲我的場景找到答案。 – w00t 2010-10-26 11:55:16

+0

優雅的解決方案是重定向'done'來覆蓋文件;這樣,整個循環體被重定向,並且該文件被打開以便只寫一次,在循環內重複進行。 – tripleee 2016-09-21 14:29:52

1

你不應該使用ls的方式。另外,ls -l爲您提供您不需要的信息。將-f選項設置爲grep將允許您將模式傳送到grep。始終引用包含文件名的變量。

for i in access.log*; do awk 'END {sub(":.*","",$4); print substr($4,2)}' "$i" | grep -f - $i > "$i.output"; done 

我也消除了tailcut因爲AWK可以做他們的工作。

+0

我認爲ls -l沒有問題,這是我習慣使用它的方式。我可以使用ls -1,但它並不重要。由於AWK讀取整個文件以達到END,並且當文件大小爲500 + mb時,AWK不是剪切和剪切作業的理想選擇。現在關於grep -f,這真的很有幫助。謝謝。 – w00t 2010-11-02 08:19:20

+1

http://mywiki.wooledge.org/ParsingLs解釋了爲什麼'ls'有問題。 – tripleee 2016-09-20 05:27:10

0

你可以試試:

grep "$(stuff to get piped over to be grep-ed)" file 

我沒有嘗試這樣做,但在這裏應用於我的回答是這樣的:

grep "$(for i in `ls -1 access.log*`; do tail $i |awk {'print $4'} |cut -d: -f 1 |grep - $i > $i.output; done)" $i 
相關問題