3개 파일의 bash 스크립트 입력

3개 파일의 bash 스크립트 입력

원시 데이터로 이 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.

배쉬 프로그램이란 무엇입니까?

도와주세요.

아래 코드를 시도 중이지만 일치하는 사용자 대신 모든 사용자가 인쇄됩니다.

#!/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'

관련 정보