将一个命令的输出作为参数传递给另一个命令

发布于 2024-09-29 06:41:40 字数 602 浏览 5 评论 0原文

我有这个用于

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等
tail 会给我每个文件的最后一行,如下所示: 192.168.1.23 - - [08/Oct/2010:14:05:04 +0300] 等等等
awk+cut 将提取日期(2010 年 10 月 8 日 - 但每个 access.log 中都不同),这将允许我对其进行 grep 并将输出重定向到一个单独的文件。

但我似乎无法将 awk+cut 的输出传递给 grep 。

所有这一切的原因是这些访问日志包含具有多个日期的行(10 月 6 日、10 月 7 日、10 月 8 日),而我只需要具有最新日期的行。

我怎样才能实现这个目标?

谢谢。

I have this for:

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

ls will give access.log, access.log.1, access.log.2 etc.
tail will give me the last line of each file, which looks like: 192.168.1.23 - - [08/Oct/2010:14:05:04 +0300] etc. etc. etc
awk+cut will extract the date (08/Oct/2010 - but different in each access.log), which will allow me to grep for it and redirect the output to a separate file.

But I cannot seem to pass the output of awk+cut to grep.

The reason for all this is that those access logs include lines with more than one date (06/Oct, 07/Oct, 08/Oct) and I just need the lines with the most recent date.

How can I achieve this?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

幸福%小乖 2024-10-06 06:41:40

作为旁注,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

As a sidenote, tail displays the last 10 lines.

A possible solution would be to grepthis way:

for i in `ls -lf access.log*`; do grep $(tail $i |awk {'print $4'} |cut -d: -f 1| sed 's/\[/\\[/') $i > $i.output; done
雨巷深深 2024-10-06 06:41:40

你为什么不把它分成几个步骤呢?

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

why don't you break it up into steps??

for file in *access.log
do
  what=$(tail "$i" |awk {'print $4'} |cut -d: -f 1)
  grep "$what" "$file" >> output
done
橘味果▽酱 2024-10-06 06:41:40

您不应该以这种方式使用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

我还消除了 tailcut 因为 AWK 可以完成它们的工作。

You shouldn't use ls that way. Also, ls -l gives you information you don't need. The -f option to grep will allow you to pipe the pattern to grep. Always quote variables that contain filenames.

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

I also eliminated tail and cut since AWK can do their jobs.

醉生梦死 2024-10-06 06:41:40

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

man xargs

或者
http://tldp.org/LDP/Bash-Beginners-Guide/html /sect_03_04.html,第 3.4.5 节。命令替换

Umm...
Use xargs or backticks.

man xargs

or
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html , section 3.4.5. Command substitution

勿忘初心 2024-10-06 06:41:40

你可以尝试:

 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

you can try:

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

I haven't tried this, but my answer applied here would look like this:

 grep "$(for i in `ls -1 access.log*`; do tail $i |awk {'print $4'} |cut -d: -f 1 |grep - $i > $i.output; done)" $i
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文