![awk - 将 2 个步骤合并为一个步骤](https://linux22.com/image/230641/awk%20-%20%E5%B0%86%202%20%E4%B8%AA%E6%AD%A5%E9%AA%A4%E5%90%88%E5%B9%B6%E4%B8%BA%E4%B8%80%E4%B8%AA%E6%AD%A5%E9%AA%A4.png)
我需要读取 Transmission-remote 的输出表来确定是否正在下载。目前这是通过以下方式实现的
trans="transmission-remote 0.0.0.0:9092 -n $user:$pass -l"
[ "$($trans | awk '! /awk/ && /n[/]a/ {print $2}')" == "n/a" ] \
|| [[ $($trans | awk '! /awk/ && /%/ {print substr($2, 1, length($2)-1)}' | sort -n | head -n 1) -lt 100 ]]
它正在寻找是否存在字符串“n/a”或完成度<100%。按照它的编写方式,它必须对同一个表探测“传输远程”两次。
示例表输出:
ID Done Have ETA Up Down Ratio Status Name
1 100% 3.38 GB Done 0.0 0.0 1.00 Finished Fish Documentary.mkv
2 100% 5.87 GB Unknown 0.0 0.0 0.00 Idle Ethical Coding.pdf
3 100% 1.33 GB Done 0.0 0.0 1.99 Finished Bacon.jpg
4 100% 1.26 GB Unknown 0.0 0.0 0.00 Idle Eggs.png
5 100% 10.89 GB Done 0.0 0.0 1.00 Finished Invest in gold.pdf
Sum: 23.63 GB 0.0 0.0
是否有可能将 awk 参数合并为一个,或者也许有人可以建议一种更简单或更干净的方法来实现所需的结果?
最终目标是让 NAS 上的红色 LED 在下载时闪烁红光,并在所有下载完成后变为稳定的白色。
原始脚本在这里:https://pastebin.com/tKXc8mFW
答案1
看了你的pastebin帖子中的代码后,我认为:
trans="transmission-remote 0.0.0.0:9092 -n $user:$pass -l"
while
[ "$($trans | awk '! /awk/ && /n[/]a/ {print $2}')" == "n/a" ] \
|| [[ $($trans | awk '! /awk/ && /%/ {print substr($2, 1, length($2)-1)}' | sort -n | head -n 1) -lt 100 ]] \
|| find $dir -mindepth 1 -maxdepth 1 | read
do
sleep 10
done
应该是这样的(未经测试):
downloading() {
transmission-remote '0.0.0.0:9092' -n "$user:$pass" -l |
awk '($2 ~ "[/%]") && ($2+0 < 100){f=1; exit} END{exit !f}' ||
find "$dir" -mindepth 1 -maxdepth 1 | read -r
}
while downloading; do
sleep 10
done
解释:
我认为您问题中的表格可能是示例输入,但它不包含您想要查找的任何值:
存在字符串“n/a”或完成度 <100%
我认为它必须位于给定代码的第二列中,因此它对于测试没有用。
如果我们修改它以包含其中一些目标值:
$ cat file
ID Done Have ETA Up Down Ratio Status Name
1 100% 3.38 GB Done 0.0 0.0 1.00 Finished Fish Documentary.mkv
2 25% 5.87 GB Unknown 0.0 0.0 0.00 Idle Ethical Coding.pdf
3 100% 1.33 GB Done 0.0 0.0 1.99 Finished Bacon.jpg
4 77% 1.26 GB Unknown 0.0 0.0 0.00 Idle Eggs.png
5 n/a 10.89 GB Done 0.0 0.0 1.00 Finished Invest in gold.pdf
并改变这个:
trans="transmission-remote 0.0.0.0:9092 -n $user:$pass -l"
对此:
trans() { transmission-remote '0.0.0.0:9092' -n "$user:$pass" -l; }
要解决您的其他问题,您应该将代码存储在函数中,而不是变量中(请参阅https://mywiki.wooledge.org/BashFAQ/050)然后将其更改为:
trans() { cat file; }
现在让我们用上面的输入进行测试,那么听起来你想要的是:
$ trans | awk '($2 ~ "[/%]") && ($2+0 < 100)'
2 25% 5.87 GB Unknown 0.0 0.0 0.00 Idle Ethical Coding.pdf
4 77% 1.26 GB Unknown 0.0 0.0 0.00 Idle Eggs.png
5 n/a 10.89 GB Done 0.0 0.0 1.00 Finished Invest in gold.pdf
但鉴于您的问题没有预期的输出,这只是一个猜测。
如果满足任何条件,您也可能只想获得成功/失败退出状态,在这种情况下,情况是:
$ if trans | awk '($2 ~ "[/%]") && ($2+0 < 100){f=1; exit} END{exit !f}'; then
echo "found it"
fi
found it
或者如果您想在trans
每秒调用一次的循环中执行此操作,直到 awk 脚本成功退出(意味着未找到目标):
$ while trans | awk '($2 ~ "[/%]") && ($2+0 < 100){f=1; exit} END{exit !f}'; do
echo "flash red"
sleep 1
done
flash red
flash red
flash red
flash red
答案2
如果在第二列中找到“n/a”,或者第二列小于 100%,则以下 AWK 调用将成功退出,否则失败:
awk 'BEGIN { r = 1 } $2 == "n/a" || ($2 ~ "%" && int($2) < 100) { r = 0; exit } END { exit r }'
在你的脚本中,它变成了
while
$trans | awk 'BEGIN { r = 1 } $2 == "n/a" || ($2 ~ "%" && int($2) < 100) { r = 0; exit } END { exit r }' \
|| find $dir -mindepth 1 -maxdepth 1 | read
do
sleep 10
done
AWK 脚本在第 2 列中查找“n/a”或转换为整数后小于 100 的百分比值。