#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
$