无法捕获过去 bash 命令的输出
Can't capture the ouput of the paste bash command
( ping -n apple.com | ack -o --flush '((?<=icmp_seq=)[0-9]+|(?<=time=)[0-9]+[.][0-9]+)' | paste - - ) > ~/Desktop/ping_ouput.txt
由于某种原因似乎无法正常工作,而如果我拿走
| paste - -
节,效果很好。我需要用制表符而不是换行符将每一行连接在一起。任何想法表示赞赏。
更新:
默认情况下,ping
无限期地产生输出 ,直到终止 ,因此您的管道将继续产生输出并增加无限期地输出文件,你的命令永远不会自己完成。
因此,您需要限制执行的 ping 次数;例如:
- 使用
-c count
选项在指定的 ping 次数后停止。
- 或者,在类似 BSD 的系统上,您可以使用
-o
在第一个 成功 ping 之后停止。
- 或者,您可以在指定的超时秒数后停止,而不管收到了多少数据包:
- Linux:
-w timeout
- 类 BSD 系统:
-t timeout
顺便说一句,为了将管道重定向到文件,不需要将它作为一个整体包含在(...)
中,这不必要地创建了一个(另一个) 子壳.
以下内容是在 (a) 已知特定症状和 (b) OP 在评论中透露他们的平台是 OSX 之前编写的。下面的命令显示了 OP 提取命令的替代方法; -c 2
已添加以将 ping 限制为 2 次尝试。
在您的命令中发现了至少 潜在的 问题:假设 time
值 always有一个小数点,在 Linux 平台上不成立;然而,在 BSD/OSX 平台上,总是 3 位小数。
您可以绕过这个问题以及合并连续行的需要,如下所示(我使用 127.0.0.1
而不是 apple.com
以便于测试):
使用 GNU sed
(Linux) 或 BSD sed
(类 BSD 系统,包括 OSX):
ping -c 2 -n 127.0.0.1 |
sed -E '1d; s/^.* icmp_seq=([^ ]+).* time=([^ ]+).*$/'$'\t''/'
备选方案,使用awk
:
ping -c 2 -n 127.0.0.1 | awk -F'[ =]' -v OFS='\t' 'NR>1 { print , }'
如果您不想依赖字段 indices,这里有一个替代方案(仍然依赖字段 icmp_seq
来 before time
,并且两者前面都有 space):
ping -c 2 -n 127.0.0.1 | awk -F' (icmp_seq|time)=' -v OFS='\t' '
NR>1 { sub(" .+$", "", ); sub(" .+$", "", )
print , }'
您没有提供从 ping
获得的样本输入,因此不清楚您的问题是什么。但我猜你的问题是因为 ping
结果中的 time
部分可能并不总是包含点 .
,例如: 64 bytes from x.x.x.x: icmp_seq=1 ttl=63 time=137 ms
。您可能想尝试使用以下命令:
( ping -n yahoo.com \
| ack -o --flush '((?<=icmp_seq=)\d+|(?<=time=)[\d.]+)' \
| stdbuf -o0 paste - - \
) > ~/Desktop/ping_ouput.txt
编辑:根据 OP 的评论,问题实际上可能来自缓冲的 paste
命令。请尝试将 stdbuf -o0
添加到 paste
命令。
( ping -n apple.com | ack -o --flush '((?<=icmp_seq=)[0-9]+|(?<=time=)[0-9]+[.][0-9]+)' | paste - - ) > ~/Desktop/ping_ouput.txt
由于某种原因似乎无法正常工作,而如果我拿走
| paste - -
节,效果很好。我需要用制表符而不是换行符将每一行连接在一起。任何想法表示赞赏。
更新:
默认情况下,ping
无限期地产生输出 ,直到终止 ,因此您的管道将继续产生输出并增加无限期地输出文件,你的命令永远不会自己完成。
因此,您需要限制执行的 ping 次数;例如:
- 使用
-c count
选项在指定的 ping 次数后停止。 - 或者,在类似 BSD 的系统上,您可以使用
-o
在第一个 成功 ping 之后停止。 - 或者,您可以在指定的超时秒数后停止,而不管收到了多少数据包:
- Linux:
-w timeout
- 类 BSD 系统:
-t timeout
- Linux:
顺便说一句,为了将管道重定向到文件,不需要将它作为一个整体包含在(...)
中,这不必要地创建了一个(另一个) 子壳.
以下内容是在 (a) 已知特定症状和 (b) OP 在评论中透露他们的平台是 OSX 之前编写的。下面的命令显示了 OP 提取命令的替代方法; -c 2
已添加以将 ping 限制为 2 次尝试。
time
值 always有一个小数点,在 Linux 平台上不成立;然而,在 BSD/OSX 平台上,总是 3 位小数。
您可以绕过这个问题以及合并连续行的需要,如下所示(我使用 127.0.0.1
而不是 apple.com
以便于测试):
使用 GNU sed
(Linux) 或 BSD sed
(类 BSD 系统,包括 OSX):
ping -c 2 -n 127.0.0.1 |
sed -E '1d; s/^.* icmp_seq=([^ ]+).* time=([^ ]+).*$/'$'\t''/'
备选方案,使用awk
:
ping -c 2 -n 127.0.0.1 | awk -F'[ =]' -v OFS='\t' 'NR>1 { print , }'
如果您不想依赖字段 indices,这里有一个替代方案(仍然依赖字段 icmp_seq
来 before time
,并且两者前面都有 space):
ping -c 2 -n 127.0.0.1 | awk -F' (icmp_seq|time)=' -v OFS='\t' '
NR>1 { sub(" .+$", "", ); sub(" .+$", "", )
print , }'
您没有提供从 ping
获得的样本输入,因此不清楚您的问题是什么。但我猜你的问题是因为 ping
结果中的 time
部分可能并不总是包含点 .
,例如: 64 bytes from x.x.x.x: icmp_seq=1 ttl=63 time=137 ms
。您可能想尝试使用以下命令:
( ping -n yahoo.com \
| ack -o --flush '((?<=icmp_seq=)\d+|(?<=time=)[\d.]+)' \
| stdbuf -o0 paste - - \
) > ~/Desktop/ping_ouput.txt
编辑:根据 OP 的评论,问题实际上可能来自缓冲的 paste
命令。请尝试将 stdbuf -o0
添加到 paste
命令。