我有一个.txt
包含 5 个 URL 的文件。我想逐行读取它,并为每个站点执行 4 个 ping 请求,然后提取时间。我写的代码如下,但它不起作用。
有人可以给我提示吗?
#!/bin/bash
cat /home/akis/Desktop/sites.txt
declare -i var=1
while read -r line
do
while $var <= 5
do
var2=$((var2+1))
name="$line" | ping -c 4 $name > $var.txt | awk '{ print $8 }' < $var.txt | awk '/time/' > $var2.txt | tr '=' '\t' < $var2.txt | awk '{ print $2 }' > $var2.txt
done
var=$((var+1))
done
答案1
这也Sergiy 的回答来自循环遍历包含 URL 的文本文件并对每个文件执行 ping。
假设文件urls
位于当前目录中并包含您的 url仅有的,每行一个:
#!/bin/bash
while IFS='' read -r l || [ -n "$l" ]; do
avg=$(ping -q -w 10 "$l" | sed '$!d;s_.*=[^/]*/\([^/]*\)/.*_\1_')
echo "Average respond time for $l: $avg ms" >> avg_time
done < "urls"
示例运行
上面的脚本在这里被命名avg
。
$ cat urls
askubuntu.com
unix.stackexchange.com
stackoverflow.com
$ ./avg
$ cat avg_time
Average respond time for askubuntu.com: 37.742 ms
Average respond time for unix.stackexchange.com: 35.966 ms
Average respond time for stackoverflow.com: 38.982 ms
解释
#!/bin/bash
这个所谓的舍邦定义你的脚本必须从哪个 shell 启动,这里是bash
while IFS='' read -r l || [ -n "$l" ]; do stuff; done < "urls"
read
逐行命名文件urls
,将当前处理行的内容赋给变量l
并执行stuff
用它ping -q -w 10 "$l"
(=ping -qw10 "$l"
)
调用ping
,使用变量的内容l
作为参数,并使用选项-q
uiet(我们不需要的较少输出)和-w 10
(以秒为单位的超时时间),以便当前处理的 URL 被 ping 精确的10
秒数——您可以根据需要调整此值,也可以指定其他选项(请参阅man ping
) 查看列表)avg=$(ping … | sed …)
将输出管道传输到ping
其中以sed
减少平均响应时间并将该值保存在变量中avg
sed '$!d;s_.*=[^/]*/\([^/]*\)/.*_\1_'
sed '$!d
不要(!
)d
删除最后一行($
),而是删除其余部分sed 's/a/b/'
s
ubstitutea
byb
– 也可以写成例如sed 's_a_b_'
,这样我们就不需要在字符串中转义文字斜杠字符.*
– 拿走一切=
和/
– 文字“=”和“/”[^/]*
^
– 取除 ( ) 斜线之外的所有内容\([^/]*\)
– 取出所有不是 (^
) 斜线的内容并将其保存到组中\1
– 第一组保存\(…\)
之前
- 也可以使用以下方法完成相同的工作
awk -F/ '/^rtt/{print$5}'
:-F/
– 定义/
为F
字段分隔符/^rtt/{…}
^
– 选择以“rtt”开头的行( )并执行…
该操作print$5
–print
仅限字段编号。5
echo "Average respond time for $l: $avg ms" >> avg_time
打印插入变量内容的文本l
并将avg
此输出重定向到文件avg_time
并附加到其内容
答案2
对于诸如 这样的单个简单命令ping
,可以使用xargs
。 很酷的是,xargs
它有--arg-file
一个选项,允许您指定xargs
将用于为您尝试运行的命令提供位置参数的文件;在您的例子中,这将是文本文件中每行一个站点。
具体来说,您想要的命令是这样的:
xargs -I% --arg-file=./input.txt ping -c 4 %
-I
允许我们为每个参数选择占位符,其xargs
内部将--arg-file
是位置参数的来源文件;请注意,我们使用 来./
指示文件位于当前工作目录中ping -c 4
将尝试使用4 个数据包访问ping
来自的每个站点input.txt
请注意,我们还可以使用-q
选项来ping
阻止打印每个接收/发送的数据包的行,而只输出统计信息。从那里,我们可以使用awk
或任何其他文本处理实用程序进一步清理输出(请记住,输出将在通过管道时进行缓冲,并等待ping
实际完成并输出统计信息,因此在屏幕上显示会有点慢):
$ xargs -I% --arg-file=./input.txt ping -c 4 % -q | awk '/^---/||/avg/'
--- askubuntu.com ping statistics ---
rtt min/avg/max/mdev = 49.677/73.403/94.312/19.276 ms
--- unix.stackexchange.com ping statistics ---
rtt min/avg/max/mdev = 40.015/59.099/115.545/32.590 ms
--- stackoverflow.com ping statistics ---
rtt min/avg/max/mdev = 40.130/40.878/42.685/1.056 ms
$ xargs -I% --arg-file=./input.txt ping -c 4 % -q | awk -F'[ /]' '/^---/{print $2};/avg/{print $8}'
askubuntu.com
39.809
unix.stackexchange.com
189.557
stackoverflow.com
161.974