Unix 将一个命令的输出作为参数传递给另一个命令
我有这个: ls将提供access.log、access.log.1、access.log.2等Unix 将一个命令的输出作为参数传递给另一个命令,unix,shell,awk,grep,design-patterns,Unix,Shell,Awk,Grep,Design Patterns,我有这个: ls将提供access.log、access.log.1、access.log.2等 tail将给出每个文件的最后一行,看起来像:192.168.1.23---[08/Oct/2010:14:05:04+0300]等 awk+cut将提取日期(2010年10月8日-但在每个access.log中不同),这将允许我对其进行grep并将输出重定向到单独的文件 但我似乎无法将awk+cut的输出传递给grep 原因是这些访问日志包含多个日期的行(06/10月、07/10月、08/10月),
tail将给出每个文件的最后一行,看起来像:
192.168.1.23---[08/Oct/2010:14:05:04+0300]
等awk+cut将提取日期(2010年10月8日-但在每个access.log中不同),这将允许我对其进行grep并将输出重定向到单独的文件 但我似乎无法将awk+cut的输出传递给grep 原因是这些访问日志包含多个日期的行(06/10月、07/10月、08/10月),我只需要最新日期的行 我怎样才能做到这一点 谢谢。嗯。。。 使用xargs或backticks
man xargs
或
,第3.4.5节。命令替换为什么不将其分解为多个步骤
for file in *access.log
do
what=$(tail "$i" |awk {'print $4'} |cut -d: -f 1)
grep "$what" "$file" >> output
done
作为旁注,
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
你不应该那样使用
ls
。另外,ls-l
提供您不需要的信息。grep
的-f
选项将允许您通过管道将模式传输到grep
。始终引用包含文件名的变量
for i in access.log*; do awk 'END {sub(":.*","",$4); print substr($4,2)}' "$i" | grep -f - $i > "$i.output"; done
我还消除了tail
和cut
,因为AWK可以完成它们的工作。您可以尝试:
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
您可以发布一些示例输入和预期输出吗?一个问题是,您一直在为每个access.log覆盖相同的输出。注意,您还可以为tail.lol.使用多个文件。。你说得对,我不知道我怎么忽略了这个事实。让我想想,这样我就可以想出一个解决办法。只需添加一个附加到日志的计数器name@tripleee感谢您的反馈,但这个问题是在2010年提出的。这也会在每次迭代中覆盖
输出
。我想我可以分解它,但我想从CLI运行它。无论如何,我不止一次需要使用这样的功能,所以我正在尝试为我的场景找到答案;通过这种方式,整个循环体被重定向,文件只被打开一次以供写入,而不是在循环内部重复写入。我不太关心这方面。我本可以用tail-n1。@mouviciel-我已经完全按照你写的那样试过了,但它给出了grep:Unmatched[或[^I,我知道,[
对grep
有特殊的意义。我编辑了我的答案。sed's#\[###g'-这一个有效。尽管如此,我仍然对我最初的问题感到好奇。似乎这是唯一的解决方案,在你需要的命令中写入所有其他命令。因此,在我的例子中,它是:对于我来说,在'ls-lf access.log*';do grep$(tail$I | awk{print$4}cut d:-f1 | sed's#[#g'))$i>$i.output;完成。感谢您的支持。我不知道xargs如何帮助我。它需要知道以前所有命令的输出是什么,然后将其作为模式传递给grep。它不是command | xargs grep 123 file.txt
,而是command | xargs grep-pattern from command-file.txt
,我看不出有问题我使用ls-l,这是我习惯使用它的方式。我本可以使用ls-1,但它并不重要。AWK不是tail and cut工作的理想人选,因为AWK读取整个文件直到结束,当一个文件的大小超过500 mb时,它需要的时间太长。现在关于grep-f,这真的很有帮助。谢谢。解释为什么ls
有问题马蒂奇。
grep "$(for i in `ls -1 access.log*`; do tail $i |awk {'print $4'} |cut -d: -f 1 |grep - $i > $i.output; done)" $i