1

私は次のフラットファイルを持っていますemployees.txt

100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000

各部門の人数を数えたい。次のようなコマンドを使用してこれを行うより短い方法があることは知っていますがawk '{print $4}' employees.txt | sort | uniq -c、入力を行ごとに読み取って、whileループの仕組みを学びたいと思います。

#!/bin/bash
awk '{print $4}' employees.txt > temp_file

array=[]
while read line
do
        if [[ $array[$line] ]]
        then
                $array[$line]=$(($array[$line]+1))
        else
                $array[$line]=0
        fi
done < temp_file

このスクリプトを実行すると、エラーが発生します./process.sh: line 9: [][Sales]+1: syntax error: operand expected (error token is "[][Sales]+1")

doneまた、キーワードの後に​​4列目のエントリを取得するために使用できる構文はありますか?私は試しdone < awk '{print $4}' employees.txtましたが、それは正しくありませんでした。

また、の出力をawk '{print $4}' employees.txt > temp_file一時ファイルではなく変数に保存する方法はありますか?

4

4 に答える 4

1
#!/bin/bash

awk '{print $4}' employees.txt > temp_file
declare -A array
while read line
do
        if [[ ${array["$line"]} ]]; then
          array["$line"]=$(( ${array["$line"]} + 1 ))
        else
          array["$line"]=1
        fi
done < temp_file

for k in "${!array[@]}"; do
  echo "$k ${array[$k]}"
done
于 2013-03-10T01:30:52.293 に答える
1

awk の使用は必須ではありません。次のようなことを試すことができます:

#!/bin/bash       # bash 4
declare -A DEPARTMENT
while read -a field
do
  (( DEPARTMENT[${field[3]}]++ ))
done < employees.txt

for dep in "${!DEPARTMENT[@]}"
do
  printf "%s\n" "$dep ${DEPARTMENT[$dep]}"
done
于 2013-03-10T07:56:53.443 に答える
0
array=[]

正しくありません。Bash配列は次のように宣言されます

declare -A array=()

またはおそらくただ

array=()

また、doneキーワードの後に​​、4番目の列のエントリを取得するために使用できる構文はありますか?私は試したdone < awk '{print $4}' employees.txt

プロセス置換を試すことができます

done < <(awk '{print $4}' employees.txt)
于 2013-03-10T01:16:55.030 に答える
0

最初の 2 つのソリューションbash(これは、他の与えられたソリューションと似ていますが、より簡潔です - を使用するawk代わりに、4 番目の列を引き出すために を使用しませんread)。

まず、bash実装:

#!/usr/bin/bash

declare -A dept
while read -r _ _ _ d _; do
   ((dept[$d]++))
done <<-'!'
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000
!

for d in "${!dept[@]}"; do
   printf '%s %d\n' "$d" "${dept[$d]}"
done

awk実装は非常に似ています:

awk '
   {
      dept[$4]++;
   }
   END {
      for (d in dept)
         print d, dept[d]
   }
' <<'!'
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000
!
于 2013-03-10T19:33:04.110 に答える