2010-08-03 159 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来实现。