将长单行命令转换为bash shell脚本

时间:2017-09-21 08:30:01

标签: linux bash shell awk

我在crontab中处理以下命令:

nice --20 iperf3 -c somelocation.com -f k | while IFS= read -r line; do echo "$(date) $line"; done | tee onespeed.txt | tee -a speeds.txt; sleep 30 ;cat onespeed.txt | grep sender >> concentrated.txt; sleep 2 ;cat onespeed.txt | grep sender | awk -F' ' '{print $13}' | while IFS= read -r line; do echo "$(date) $line"; done | tee onerawspeed.txt | tee -a rawspeeds.txt

我知道这项工作可以以更优雅的方式完成,但我正在寻找如何解决这个问题,以便它的结构能够恰当地充当bash shell脚本。

具体而言,我专注于在多行上构建它,以便更具可读性。

3 个答案:

答案 0 :(得分:1)

由于目前还不清楚你真正想要放在所有这些输出文件中,我将举例说明如何将不同的值写入不同的文件。

每个时间间隔的比特率p / sec和iperf3产生的平均比特率可以放在这样的文件中:

$ cat tst.awk
BEGIN {OFS="\t";f1="speed.txt";f2="sender.txt"}
$6~/MBytes/{print strftime(), $7 >> f1; close(f1)}
/sender/{print strftime(), $7 >> f2; close(f2)}

可以像这样调用:

$ iperf3 -c server -f k --forceflush | awk -f tst.awk

或者,在一行中:

 iperf3 -c server -f k --forceflush | awk -v f1=speed.txt -v f2=sender.txt \
    'BEGIN{OFS="\t"}                                          \
     $6~/MBytes/{print strftime(), $7 >> f1; close(f1)}       \
     /sender/{print strftime(), $7 >> f2; close(f2)}'

将sysdate和Bitrate打印到每个文件,由\ t分割。你需要iperf3的forceflush选项来防止输出缓冲,这会导致awk脚本为每一行打印相同的时间戳。

答案 1 :(得分:1)

将代码包装在任意函数n() { one-liner_code_here ; }中,然后运行type nbash将充实它的大部分内容 - 特别有用的是如何缩进循环。但是type不会破坏管道,并留下分号,所以这里有一些代码可以使整个业务自动化......

假设单行是文件 src 。下面将 src 放入$x,然后为它创建一个函数 n (这需要一个eval,它对于函数中的带引号的字符串应该是无害的),并type它,将sed提供给忽略周围括号的;,打破较长的管道并移除前导凹痕和&amp ;;尾随unset,然后read x <src; eval n\(\) \{ "$x" \;\} type n | sed -n '/^ /{s/^ //;/^[^ ]/s/| /|\n/g;s/\;$//;p}' ; unset -f n s n

nice --20 iperf3 -c somelocation.com -f k |
while IFS= read -r line; do
    echo "$(date) $line"
done |
tee onespeed.txt |
tee -a speeds.txt
sleep 30
cat onespeed.txt |
grep sender >> concentrated.txt
sleep 2
cat onespeed.txt |
grep sender |
awk -F' ' '{print $13}' |
while IFS= read -r line; do
    echo "$(date) $line"
done |
tee onerawspeed.txt |
tee -a rawspeeds.txt

输出:

type

注意:alias还会将当前环境中的任何grep转换为代码。因此,如果aliasgrep --color=auto添加到grep,则上面的每个grep --color=auto都会被{{1}}替换。

答案 2 :(得分:0)

nice --20 iperf3 -c somelocation.com -f k | while IFS= read -r line; do 
echo "$(date) $line" 
done | tee onespeed.txt | tee -a speeds.txt
sleep 30 
grep "sender" onespeed.txt >> concentrated.txt
sleep 2 
awk -F' ' '/sender/ {print $13}' onespeed.txt | while IFS= read -r line; do
echo "$(date) $line"
done | tee onerawspeed.txt | tee -a rawspeeds.txt

编辑: 我已按照评论建议更新了脚本