複数の従業員を含むテキストファイルがあります。テキストファイルはこのスキームに従います。
寺名部門 20.00
毎日の賃金を計算するには、変数付きのawkコマンドが必要です。また、各フィールドをタブとドル記号で区切って、1時間あたりの毎日のレートと/ hrと/日の末尾のテキストを表示する必要があります。例えば
従業員名部門 $20.00/時間 $160/日 従業員名部門 $50.00/時間 $400/日 従業員名部門 $200.00/時間 $1600/日
また、すべての労働者の1時間あたりの賃金を合計して表示し、「労働者は1時間あたり合計889ドル(または総額)を稼ぐ」というテキストを表示する必要があります。
私は初めてawkに触れて、インターネット検索を試しましたが、どこから始めるべきかわかりません。
答え1
awk '{$NF="$"$NF"/hr " "$"$NF*8"/day";print $0}' filename
出力
Adam Adamson Accounting $20.00/hr $160/day
Iver Iverson InfoTech $50.00/hr $400/day
Cary Caryson ChiefExecutive $200.00/hr $1600/day
Mary Maryson Maintenance $15.00/hr $120/day
Stan Stanson SalesDept. $10.00/hr $80/day
Scot Scotson SalesDept. $10.00/hr $80/day
Eric Ericson Executive $100.00/hr $800/day
Enid Enidson Executive $100.00/hr $800/day
Maye Mayeson Maintenance $15.00/hr $120/day
Axel Axelson Accounting $21.00/hr $168/day
Pete Peteson PayrollDept. $15.50/hr $124/day
Mick Mickson Marketing $12.00/hr $96/day
Iris Irisson InfoTech $55.00/hr $440/day
Hank Hankson HumanRes $42.42/hr $339.36/day
答え2
awk -v hpd=8 '
{ printf "%s\t%s\t%s\t$%.2f/hr\t$%.2f/day\n", $1, $2, $3, $4, $4 * hpd;
ht += $4; # hourly total
};
END {
printf "\nWorkers earned a combined $%.2f per hour\n", ht
}
' input.txt
Adam Adamson Accounting $20.00/hr $160.00/day
Iver Iverson InfoTech $50.00/hr $400.00/day
Cary Caryson ChiefExecutive $200.00/hr $1600.00/day
Mary Maryson Maintenance $15.00/hr $120.00/day
Stan Stanson SalesDept. $10.00/hr $80.00/day
Scot Scotson SalesDept. $10.00/hr $80.00/day
Eric Ericson Executive $100.00/hr $800.00/day
Enid Enidson Executive $100.00/hr $800.00/day
Maye Mayeson Maintenance $15.00/hr $120.00/day
Axel Axelson Accounting $21.00/hr $168.00/day
Pete Peteson PayrollDept. $15.50/hr $124.00/day
Mick Mickson Marketing $12.00/hr $96.00/day
Iris Irisson InfoTech $55.00/hr $440.00/day
Hank Hankson HumanRes $42.42/hr $339.36/day
Workers earned a combined $665.92 per hour
最初のコードブロック(つまり、最初の中かっこペアの内側{
)}
は、入力ファイル(input.txt
この場合)の各行に対して実行されます。このEND {...}
ブロックは、すべての入力を読み取って処理した後に一度だけ実行されます。
hpd=8
コマンドラインセクションを変更して、1日の時間数を変更できます。 8つにハードコードすることもできますが、変数にするのがもっと面白いと思います。
練習で最終printf
明細を編集して、1日の合計も印刷できることを確認してください。これを理解することで、printfステートメントが何をしているのかを理解するのに役立ちます。出力は次のようになります。
Workers earned a combined $665.92 per hour or $5327.36 per day
答え3
難しい方法。多次元配列のみを使用するGNU awkの場合。列の形式は、内容の長さに関係なく保持されます(column -t
このユーティリティを使用する場合と同様)。区切り文字は、OFS 変数でグローバルに定義されます。
awk -v pre="$" -v suf="/hr" '
{hr+=$NF;
for(i=1; i<=NF; i++) {
row[NR][i]=$i
l=length($i)
if(l>len[i]) len[i]=l
}
}
END {for(i in row){
for(j in row[i])
printf("%-*s" OFS, (j==NF?4:0) + len[j],
j==NF? pre row[i][j] suf: row[i][j])
print pre row[i][j] * 8 "/day"
}
print "\nworkers earned a combined $" hr " per hour"
}
' OFS='\t' file
最初の部分では、印刷時に各列の最大幅が計算され、それに応じてインデントされます。
答え4
awkを使うべきですか?
#!/bin/bash
while IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; do
a=($(echo "$LinefromFile"))
printf "%-20s" $a[1] $a[2] $a[3]
printf "%-20s%.2f" $a[4] $((a[4] * 8))
printf "\n"
done < "$1"