2010-08-03 158 views
4

我通過多個命令試圖管的awk命令的輸出一次在Bash shell,下面我所知,我來了這一點:在shell(bash)中如何在管道中執行多個命令?

awk '$13 ~ /type/ {print $15}' filename.txt | (wc -l || sort -u) 

我想awk的結果命令被計數和排序,我怎麼能做到這一點? 即使使用& &命令它不起作用,它執行第一個命令,然後退出。 我想這是我對bash的知識,這是失敗的。

在此先感謝。

回答

5

如果你想在一行中將輸出發送到兩個不同的命令,你需要進行過程替代。

試試這個:

awk '$13 ~ /type/ {print $15}' filename.txt | tee >(wc -l >&2) | sort -u 

此輸出stderr上線數,並在標準輸出上有序輸出。如果你需要stdout的行數,你可以做到這一點,離開>&2,但它會傳遞給排序調用,並且(很可能)排序到輸出的頂部。

編輯:更正基於進一步測試發生了什麼的描述。

+0

它不起作用:/ – OverLex 2010-08-03 15:43:29

+0

@Lex:如果bash被調用爲'sh',它將進入兼容模式,並且進程替換不起作用。顯式調用shell爲'bash',它應該沒問題。 – goldPseudo 2010-08-03 15:48:00

+0

這可行,但它不是很整齊: awk'$ 13〜/ type/{print $ 15}'filename.txt | tee test.txt |排序-u; cat test.txt | wc -l – OverLex 2010-08-03 15:48:17

0

我認爲更大的問題是:你期望輸出是什麼?

如果你試圖做兩件事情,然後做兩件事情:

awk '$13 ~ /type/ {print $15}' filename.txt > tempfile 
wc -l < tempfile 
sort -u < tempfile 
rm tempfile 
+0

我希望我的輸出是兩行或多行,一行結果(行數),另一行(或更多)結合awk命令的結果。 我想知道是否可以在一行上做到這一點,因爲我不得不重複awk命令或將其結果賦給變量。 – OverLex 2010-08-03 15:34:41

+0

請參閱我的編輯,以瞭解如何在不重複awk的情況下執行此操作。一般來說,即使你找到一種方法去做你想做的事,不要這樣做。你永遠不應該故意寫混淆的代碼。 – riwalk 2010-08-03 15:36:15

+0

我沒有覺得困惑,我只是認爲這樣做更有效率。 – OverLex 2010-08-03 15:40:41

4

在那種情況下,你在awk中計數,爲什麼需要管道?不要讓問題更加複雜

awk '$13 ~ /type/ {print $15;c++}END{print c} ' filename.txt | sort -u 
+0

這是解決它的另一種方法,謝謝! – OverLex 2010-08-03 15:52:33

1

如果輸出規模不是太大,無法在內存中,你不需要wcsort命令在性能方面的原因並行工作,這裏有一個相對簡單的解決方案:

output=$(awk '$13 ~ /type/ {print $15}' filename.txt; echo a) 
printf "%s" "${output%a}" | sort -u 
printf "%s" "${output%a}" | wc -l 

與額外a即併發症是萬一awk命令可能在輸入,其$()構建體將帶的端部打印一些空行。您可以輕鬆選擇首先出現sortwc中的哪一個。


下面是(灰時,bash和ksh,zsh的,...),但只有在具有/dev/fd系統與任何POSIX外殼的作品(包括合理最近的Linux,* BSD和Solaris)的方式。與Walter's similar construction using the simpler method available in bash, ksh93 and zsh類似,wc的輸出和sort的輸出可以混合。

{ 
    awk '$13 ~ /type/ {print $15}' filename.txt | 
    tee /dev/fd3 | 
    wc -l 
} 3>&1 1>&3 | sort -u 

如果同時需要處理中間輸出不舒服適合在內存不想有混雜,我不認爲有兩個命令的輸出在POSIX shell中一個簡單的方法,但它應該可以用ksh或zsh coprocesses來實現。