さまざまなユーザーデータを含む2つのcsvファイルがあります。それらは1つの共通フィールド(ユーザー名)を共有します。
file A:
username ; Fullname ; mail
Bob ; Bob Hope ; [email protected]
file B:
username ; LastLogonTime ; AccountStatus (locked=0 or unlocked=1)
Bob ; 2018-10-01 etc.; 0
監査の目的で、Bashを使用してAをループし、アカウントがロックされているかどうかをBとクロスチェックします。この場合、ユーザーをAのメールアドレスに送信できます。
awk -F";"
aを超えることができます。簡単ですが、Bでクロスチェックループを実行しようとすると途方に暮れます。
awk
を使用して、最初に2番目のファイルからアカウントがロックされているユーザーのユーザー名を読み取り、次に最初のファイルからこれらのメールアドレスを抽出します(メールを読むためにログインする必要がないことを期待します) ):
awk -F ';' 'NR == FNR && $NF == 0 { names[$1] }
NR != FNR && $1 in names { print $NF }' B.csv A.csv
これは、各ユーザー名の両方のファイルで、ユーザー名の前後に同じ量の空白があることを前提としています。そうでない場合は、-F ' *; *'
を使用して、awk
が使用している区切り文字にスペース文字を含めることができます。また、データに;
文字が埋め込まれていないことも前提としています。
NR
は、現在のレコード全体のレコード(行)番号であり、FNR
は同じ番号ですが、現在のファイル内にあります。 NR == FNR
の場合、コマンドラインで指定された最初のファイル(B.csv
)から読み取っています。 NF
は現在のレコードのフィールド(列)の数であり、$NF
は最後のフィールドのデータです(および$1
は最初のフィールドのデータです)。
上記のコードは、最初のファイル(B.csv
)から読み取られた、ロックアウトされたユーザーのユーザー名をキーとする連想配列/ハッシュnames
を使用しています。 $1 in names
がその配列のキーである場合、$1
はtrueになります。
これをループに入れます:
awk -F ';' 'NR == FNR && $NF == 0 { names[$1] }
NR != FNR && $1 in names { print $NF }' B.csv A.csv |
while read addr; do
printf 'Would send an email to "%s"\n' "$addr"
#mail -s 'Account locked' "$addr" <template-email.txt
done
またはそれらの線に沿って何か。ループ内でこの方法で電子メールアドレスを読み取ると、周囲の空白が削除されます。上記のループは電子メールを送信しませんが、送信する必要があるアドレスを出力します。 mail
の前に#
を削除して(およびフォームメールをtemplate-email.txt
に書き込んで)、実際にメールを送信します(ただし、別の方法で送信することもできます)。
csvkit
を使用:
csvjoin -d ';' -c 1 A.csv B.csv |
csvgrep -c 5 -m False |
csvcut -S -c 3 | sed 1d
CSVkitは、CSVファイルを操作するためのCSV解析ツールを提供します。これは、CSVデータが「単純」でない場合、つまり、埋め込まれた;
文字を引用するためにCSVルールを使用する場合などに必要になります。上記のパイプラインは
0
はFalse
に変更されます)。sed
コマンドを使用)。