Среднее значение конкретного сотрудника UNIX в соответствии с назначением

#bash #shell #unix #awk #grep

#bash #оболочка #unix #awk #grep

Вопрос:

Это пример текстового файла, который будет предоставлен в качестве входных данных

   Name,Designation,Salary
  Hari,Engineer,35000
  Suresh,Consultant,80000
  Umesh,Engineer,45500
  Maya,Analyst,50000
  Guru,Consultant,100000
  Sushma,Engineer,30000
  Mohan,Engineer,30000
  

Мой код должен иметь возможность запускать поиск средней зарплаты по назначению конкретного сотрудника. Например,

 bash script.sh employees.txt Analyst
  

Тогда мой вывод должен быть

 50000
  

Мой текущий код для нахождения только среднего значения всех сотрудников не работает. Я новичок в shell. Это мой текущий код

 count="$(tail -n 1 salary.txt | grep -o '^[^s] ')"

echo "$count"
salary="$(grep -o '[^ ] $' salary.txt | paste -sd )"

echo "$salary"

echo "($salary)/$count" | bc 
  

В качестве результатов я получаю пустые значения.

Комментарии:

1. Вы можете сделать это в bash, но, возможно, вам следует рассмотреть возможность использования более универсального языка, такого как awk, Python или Ruby.

2. Что-то не так почти с каждой из этих строк. Разберите их по отдельности, одну за другой, и запустите каждую подкоманду в командной строке, чтобы посмотреть, что она делает. Затем модифицируйте, пока не будет сделано все правильно.

Ответ №1:

Это лучше сделать в awk :

 awk -F, -v dgn='Engineer' '$2 == dgn{s  = $3;   c} END{printf "%.2fn", s/c}' file.csv
  

 35125.00
  

Ответ №2:

Не могли бы вы, пожалуйста, попробовать следующее (поскольку OP запрашивал способ скрипта, поэтому добавьте его способом скрипта, где 1-й аргумент передается как имя Input_file, а 2-й аргумент — как строка, среднее значение которой необходимо).

 cat script.ksh
file="$1"
name="$2"

awk -F, -v field="$name" '{a[$2] =$3;b[$2]  } END{for(i in a){if(i == field){print a[i]/b[i]}}}'  "$file"
  

Теперь запустите скрипт следующим образом.

 ./script.ksh Input_file Analyst
50000
  

Комментарии:

1. @Джон Доу, хорошо, что ты выбрал любой ответ как правильный. Хотел бы спросить вас здесь о причине отказа от моего ответа, поскольку я написал код в соответствии с вашим запросом (хотя код anubhava sir великолепен, с ним нет проблем), пожалуйста, упомяните здесь.

Ответ №3:

GNU datamash — полезный инструмент для вычисления такого рода вещей:

 $ datamash -sHt, groupby 2 mean 3 < employees.txt
  

Объедините с grep , чтобы ограничить его только тем названием, которое вас интересует.

Ответ №4:

Если вы хотите сделать это в командной оболочке:

 #!/bin/bash
file=$1
designation=$2

# code to validate user input here ...

sum=0
count=0
while IFS=, read -r n d s; do 
    if [[ ${designation,,} == "${d,,}" ]]; then 
        (( sum  = s ))
        (( count   ))
    fi
done < "$file"

if (( count == 0 )); then 
    echo "No $designation found in $file"
else
    echo $((sum / count))
fi
  

Ответ №5:

Использование Perl

  perl -F, -lane ' if(/Engineer/) { $dsg =$F[2];$c   } END { print $dsg/$c } ' file
  

с учетом ваших входных данных

 $ cat john.txt
  Name,Designation,Salary
  Hari,Engineer,35000
  Suresh,Consultant,80000
  Umesh,Engineer,45500
  Maya,Analyst,50000
  Guru,Consultant,100000
  Sushma,Engineer,30000
  Mohan,Engineer,30000

$ perl -F, -lane ' if(/Engineer/) { $dsg =$F[2];$c   } END { print $dsg/$c } ' john.txt
35125

$