如何在 .txt 文件中的单独行上读取 URL 并 ping 每一个

Aki*_*dis 6 command-line bash scripts

我有一个.txt包含 5 个网址的文件。我想一行一行地读取它,并对每个站点执行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 
Run Code Online (Sandbox Code Playgroud)

des*_*ert 8

这以及Sergiy 的回答来自Loop over text file with URLs and execute ping on each .

假设文件urls驻留在当前目录中并且包含您的网址,每行一个:

#!/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"
Run Code Online (Sandbox Code Playgroud)

示例运行

上面的脚本在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
Run Code Online (Sandbox Code Playgroud)

说明

  • #!/bin/bash
    这个所谓的shebang定义了你的脚本必须以哪个shell开始,这里是bash
  • while IFS='' read -r l || [ -n "$l" ]; do stuff; done < "urls"
    readurls逐行命名的文件,将当前处理的行的内容分配给变量l并对其进行stuff处理
  • ping -q -w 10 "$l"(= ping -qw10 "$l")以变​​量的内容作为参数和选项uiet(我们不需要的更少输出)和(以秒为单位的超时)
    调用,以便当前处理的 URL 被 ping 精确秒 - 您可以将此值调整为您的需求以及指定其他选项(请参阅列表中的 )pingl-q-w 1010man ping
  • avg=$(ping … | sed …)
    管的输出ping,以sed该切出的平均响应时间和节省在变量这个值avg

    • sed '$!d;s_.*=[^/]*/\([^/]*\)/.*_\1_'
    • sed '$!d
      不要 ( !)d删除最后一行 ( $),而是删除整个其余行
    • sed 's/a/b/'
      substituteab-也可以写成例如sed 's_a_b_'如果有用的话,这种方式我们不需要在字符串字面逃跑斜杠字符
      • .* – 拿走一切
      • =/– 文字“=”和“/”
      • [^/]*– 把不是 ( ^) 斜线的所有东西都去掉
      • \([^/]*\)– 将除 ( ^) 以外的所有内容都保存在一个组中
      • \1- 第一组\(…\)之前保存
    • 同样的工作也可以用awk -F/ '/^rtt/{print$5}'
      • -F/– 定义/F字段分隔符
      • /^rtt/{…}– 选择^以“rtt”开头的行 ( ) 并使用它
      • print$5print只有字段编号。5
  • echo "Average respond time for $l: $avg ms" >> avg_time
    打印文本插入变量的内容l,并avg和这个重定向输出到文件avg_time附加到其内容


Ser*_*nyy 7

对于单个简单的命令,例如ping,可以使用xargs. 很酷的一点xargs是它有一个--arg-file选项,允许您指定文件,该文件xargs将用于为您尝试运行的命令提供位置参数;在您的情况下,这将是文本文件中每行一个站点。

具体你想要的命令是这样的:

xargs -I% --arg-file=./input.txt  ping -c 4 %
Run Code Online (Sandbox Code Playgroud)
  • -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
Run Code Online (Sandbox Code Playgroud)