我创建这 3 个文件的原始数据
quota username bytes
20480000 [email protected] 896
30720000 [email protected] 3002766
20480000 [email protected] 20472940
20480000 [email protected] 2351
Here I want that if bytes if any user is equal or greater than to quota then the username should be printed or I'll perform another task to block the user.
我有 3 个文件,例如:
users.txt
Output:
[email protected]
[email protected]
consumed_quota.txt
Output:
20
5
allowed_quota.txt
Output:
20
10
我希望如果[email protected]
文件中的用户users.txt
consumed_quota
等于或大于则allowed_quota
打印用户。
bash 程序是什么?
请帮忙。
我正在尝试下面的代码,但它打印的是所有用户而不是匹配的用户。
#!/bin/bash
mysql -e 'select postfix.m.quota, q.* from postfix.mailbox m, postfix.quota2 q where m.username = q.username' > /tmp/all_users_query
username=`cat /tmp/all_users_query | cut -f2 | grep -v username > /tmp/usernf`
quota=`cat /tmp/all_users_query | cut -f1 | grep -v quota > /tmp/quotaf`
consumed=`cat /tmp/all_users_query | cut -f3 | grep -v bytes > /tmp/consumedf`
function show_users()
{
username=`cat /tmp/usernf`
for i in $username
do
echo $i
done
}
function actual_quota()
{
quota=`cat /tmp/quotaf`
for i in $quota
do
akb=`echo $i/1000 | bc`
amb=`echo $akb/1000 | bc`
echo $amb
done
}
function used_quota()
{
consumed=`cat /tmp/consumedf`
for i in $consumed
do
ukb=`echo "$i/1000" | bc`
umb=`echo "$ukb/1000" | bc`
echo "$umb"
done
}
declare -a arr_users="$(show_users)"
declare -a arr_act_quota="$(actual_quota)"
declare -a arr_use_quota="$(used_quota)"
for u in ${arr_users[@]}
do
for i in ${arr_use_quota[@]}
do
# echo $i;
for j in ${arr_act_quota[@]}
do
if [ "$j" == "$i" ]
then
echo $u;
break;
fi
done
done
done
答案1
我自己创建了脚本并得到了预期的结果。
#!/bin/bash
rm -rf /tmp/over_quota_users
mysql -e 'select postfix.m.quota, q.* from postfix.mailbox m, postfix.quota2 q where m.username = q.username and q.bytes >= m.quota-bytes;' | cut -f2 | grep -v username > /tmp/over_quota_users
#Function to get users;
function show_users()
{
username=`cat /tmp/over_quota_users`
for i in $username
do
echo $i
done
}
#Function to get active users;
function check_active()
{
for i in $(show_users); do
mysql -e 'select username, active from postfix.mailbox where username = "'$i'" and active = 1;' | grep -v username
done
result=`echo $?`
echo $result
}
active_results=$(check_active $(show_users))
if [ "$active_results" == 1 ];
then
exit 0;
else
for j in $(show_users); do
#changing over quota users to inactive.
mysql -e 'update postfix.mailbox set active = '0' where username = "'$j'"';
done
rm -rf /tmp/oqa_ul_2_admin.txt
echo "" > /tmp/oqa_ul_2_admin.txt
echo "These users were over quota and active " >> /tmp/oqa_ul_2_admin.txt
echo "" >> /tmp/oqa_ul_2_admin.txt
echo "---------------------------------------" >> /tmp/oqa_ul_2_admin.txt
echo "$(show_users)" >> /tmp/oqa_ul_2_admin.txt
echo "" >> /tmp/oqa_ul_2_admin.txt
echo "---------------------------------------" >> /tmp/oqa_ul_2_admin.txt
echo "" >> /tmp/oqa_ul_2_admin.txt
/usr/bin/mail -s "Blocked Over quota and active users" [email protected] < /tmp/oqa_ul_2_admin.txt
fi
答案2
对于您的请求,您不需要将数据拆分为3个文件然后必须读取文件。您可以直接读取/tmp/all_users_query
否则,@Kusalananda,答案是一个相当充分且功能齐全的答案。
我已经检查了您所描述的文件,并确定它们源自查询(相当明显),顺序如下:
allowed_quota
users
consumed_quota
所以我想出了以下几点::
#!/bin/bash
mysql -e 'select postfix.m.quota, q.* from postfix.mailbox m, postfix.quota2 q where m.username = q.username' > /tmp/all_users_query
gawk '{ if ($3 >= $1) { printf("\n%s ", $2); } }' /tmp/all_users_query
exit 0
另一个(更好的)解决方案是在输出中添加一个附加字段(如果您在其他地方读取输出文件,则可以丢弃该字段)。附加字段称为overflow
,它显示用户已经消耗了多少溢出字节;即consumed_quota
和之间的简单区别allowed_quota
。
输出按溢出字段按降序排列,以便首先显示最高的消耗。
#!/bin/bash
mysql -e 'select postfix.m.quota, q.* from postfix.mailbox m, postfix.quota2 q where m.username = q.username' > /tmp/all_users_query
gawk '{ allowed_amount = $1; consumed_amount = $3; if (consumed_amount >= allowed_amount) { overflow = (consumed_amount - allowed_amount); printf("\n%s\t%d", $2, overflow); } }' all_users_query | sort --key=2gr
exit 0
答案3
假设这些行Output:
实际上不是数据的一部分,
$ paste users.txt consumed_quota.txt allowed_quota.txt | awk -F '\t' '$2 >= $3 { print $1 }'
[email protected]
该paste
命令创建一个制表符分隔的数据集,其中第 1 列是用户名,第 2 列是已使用的配额,第 3 列是允许的配额。
awk
如果已使用的配额大于或等于允许的配额,程序将读取此制表符分隔的数据并打印用户名。
或者,直接查询数据库以获取超出配额的用户名:
mysql -e '
SELECT q.username
FROM postfix.quota2 q
WHERE q.bytes > q.quota'