だから私は本当にここに閉じ込められています。次の形式の数百万行のデータを含むいくつかのファイルを取得しました。
username|process name|process time (in minutes)
ほぼ340万のデータ行があります。今私の仕事は、これらすべてのデータをすばやく閲覧できるスクリプトを書くことです。
したがって、デフォルトではコマンドラインでユーザー名を入力し、そのユーザー名のすべてのデータ行を抽出して追加してから表示します。これは、ユーザーの総処理時間と、このユーザーの総プロセス数と同じ意味です。
これが私が今まで持っているものなのに多くはない。
tput cup 19 10
read -p "Please Enter a UserName: " uname
それが私が持っているすべてです。どうすればいいのか知っている人はいますか?
答え1
これを例の入力ファイルとして使用しましょう。
$ cat file
jim|process1|23
bob|process2|5
jim|process3|7
awkを使う
それでは、次のシェルスクリプトを書いてみましょう。
$ cat script.sh
#!/bin/sh
read -p "Please Enter a UserName: " uname
awk -v n="$uname" -F\| '$1==n{total+=$3} END{printf "Total for %s is %s minutes\n",n,total}' file
たとえば、Jim が使用する時間を要約します。
$ sh script.sh
Please Enter a UserName: jim
Total for jim is 30 minutes
どのように動作しますか?
awk は入力ファイルの各行を暗黙的に繰り返します。スクリプトは、n
ユーザー名とtotal
ユーザーが使用した合計時間(分)という2つの変数を使用しますn
。
-v n="$uname"
これにより、awk変数が作成され、
n
ここにシェル変数の値が割り当てられますuname
。-F\|
これはawkに
|
フィールド区切り文字として使用するように指示します。$1==n{total+=$3}
最初のフィールドが
$1
ユーザー名と一致するたびに、3番目のフィールドの量だけn
合計が増えます。total
$3
END{printf "Total for %s is %s minutes\n",n,total}
ファイルの読み取りが終わったら、結果を印刷します。
シェルを使う
あるいは、シェルでループを実行することもできます。
$ cat script2.sh
#!/bin/sh
read -p "Please Enter a UserName: " uname
while IFS=\| read -r name process minutes; do
[ "$name" = "$uname" ] && total=$((total+minutes))
done <file
echo "Total for $uname is $total minutes"
デモとして:
$ sh script2.sh
Please Enter a UserName: jim
Total for jim is 30 minutes
どちらの方法も時間がかかりませんでしたが、この方法はよりawk
速いと予想されます。