如何在 Bash 中格式化更多变量并将其放入具有预期顺序的同一个 .txt 文件中?
How to format more variables in Bash and take it in same .txt file with expect order?
我正在尝试解决 Bash 中的一项挑战。我有很多包含注册数据的 .txt 文件。我想制作一个新的 .txt 文件,每天存储新的注册用户,并在文件末尾的新行中存储用户总数。
我的脚本已经几乎以正确的方式工作(从结果来看),我尝试用不同的括号解决它或将数据带到变量中。
无论如何,这是我的脚本:
route_from=/route/*
saved=daily_registrations.txt
var1=Total_registrations:
cat $route_from | cut -f1,2 -d' ' | sort -V | uniq -c > /route/$saved #Cuts New users number | file number | date
echo $var1 >> /route/$saved #"Total_registrations:"
cat $route_from | wc -l >> /route/$saved #Total user number
我希望 .txt 文件中的输出结果是这样的(我采用竖线只是为了更好地查看)。
New users number | file number | date
New users number | file number | date
New users number | file number | date
Total_registrations: number
但现在我的实际输出是这样的:
New users number | file number | date
New users number | file number | date
New users number | file number | date
Total_registrations:
number
你的最后两行每行都给出了一个指向文件的输出,根据 bash 的性质,它们都写在单独的一行上。
我建议您将它们组合起来同时输出,使用子 shell 计算行数:
echo $var1 $(cat $route_from | wc -l) >> /route/$saved
或
echo $var1 `cat $route_from | wc -l` >> /route/$saved
这应该使用相同的 echo 命令写入 $var
的内容以及文件中的行数。
除此之外,最好不要 cat
文件 a 并通过 wc
命令对其进行管道传输,这可以使用这样的重定向来完成:
wc -l < $route_from
对于我系统上大约 500 行的文件,运行 1000 次,它会快一点:
[user@host ~]$
time for i in `seq 1000`; do cat $route_from | wc -l > /dev/null; done
real 0m2.480s
user 0m0.814s
sys 0m1.783s
[user@host ~]$ time for i in `seq 1000`; do wc -l < $route_from > /dev/null; done
real 0m1.971s
user 0m0.537s
sys 0m0.855s
[user@host ~]$
所以我会这样做:
echo $var1 `wc -l < $route_from` >> /route/$saved
将最后两行替换为:
echo -e "$var1 \c" >> /route/$saved #"Total_registrations:"
cat $route_from | wc -l >> /route/$saved #Total user number
\c
将确保不附加换行符并且下一个附加从那里开始
我写了一个 POSIX awk 解决方案。
awk -v OFS=' | ' '
{
Regs[ OFS ]++
total++
}
END {
for(reg in Regs) print Regs[reg], reg
print "Total: " total
}
' /route/* |sort -V >/route/daily_registrations
OFS
:输出字段分隔符
R[ OFS ]++
:递增一个索引为前两列的数组,用|
.
分隔
END{...}
:在每个索引前加上增量,然后打印总数。
我正在尝试解决 Bash 中的一项挑战。我有很多包含注册数据的 .txt 文件。我想制作一个新的 .txt 文件,每天存储新的注册用户,并在文件末尾的新行中存储用户总数。
我的脚本已经几乎以正确的方式工作(从结果来看),我尝试用不同的括号解决它或将数据带到变量中。
无论如何,这是我的脚本:
route_from=/route/*
saved=daily_registrations.txt
var1=Total_registrations:
cat $route_from | cut -f1,2 -d' ' | sort -V | uniq -c > /route/$saved #Cuts New users number | file number | date
echo $var1 >> /route/$saved #"Total_registrations:"
cat $route_from | wc -l >> /route/$saved #Total user number
我希望 .txt 文件中的输出结果是这样的(我采用竖线只是为了更好地查看)。
New users number | file number | date
New users number | file number | date
New users number | file number | date
Total_registrations: number
但现在我的实际输出是这样的:
New users number | file number | date
New users number | file number | date
New users number | file number | date
Total_registrations:
number
你的最后两行每行都给出了一个指向文件的输出,根据 bash 的性质,它们都写在单独的一行上。 我建议您将它们组合起来同时输出,使用子 shell 计算行数:
echo $var1 $(cat $route_from | wc -l) >> /route/$saved
或
echo $var1 `cat $route_from | wc -l` >> /route/$saved
这应该使用相同的 echo 命令写入 $var
的内容以及文件中的行数。
除此之外,最好不要 cat
文件 a 并通过 wc
命令对其进行管道传输,这可以使用这样的重定向来完成:
wc -l < $route_from
对于我系统上大约 500 行的文件,运行 1000 次,它会快一点:
[user@host ~]$
time for i in `seq 1000`; do cat $route_from | wc -l > /dev/null; done
real 0m2.480s
user 0m0.814s
sys 0m1.783s
[user@host ~]$ time for i in `seq 1000`; do wc -l < $route_from > /dev/null; done
real 0m1.971s
user 0m0.537s
sys 0m0.855s
[user@host ~]$
所以我会这样做:
echo $var1 `wc -l < $route_from` >> /route/$saved
将最后两行替换为:
echo -e "$var1 \c" >> /route/$saved #"Total_registrations:"
cat $route_from | wc -l >> /route/$saved #Total user number
\c
将确保不附加换行符并且下一个附加从那里开始
我写了一个 POSIX awk 解决方案。
awk -v OFS=' | ' '
{
Regs[ OFS ]++
total++
}
END {
for(reg in Regs) print Regs[reg], reg
print "Total: " total
}
' /route/* |sort -V >/route/daily_registrations
OFS
:输出字段分隔符
R[ OFS ]++
:递增一个索引为前两列的数组,用|
.
END{...}
:在每个索引前加上增量,然后打印总数。