我有一个 bash 脚本,当像这样调用时可以工作:./stats.sh -rows test_file
该程序主要计算行平均值和中位数以及列平均值和中位数。现在对于程序,我想将文件作为标准输入传递。但是当我运行这段代码时它会打印"you have 2 provide 2 arguments"
。我应该进行哪些更改才能使代码将 stdin 作为文件。我的意思是说,如果我想运行脚本,我也可以通过这种方式运行它./stats.sh -rows < test_file
。我想要这个功能!!
输入文件是:(由制表符分隔的列)
93 93 93 93 93 93 93 93 100
73 84 95 83 72 86 80 97 100
85 0 82 75 88 79 80 81 100
85 0 87 73 88 79 80 71 100
80 81 83 63 100 85 63 68 100
53 57 61 53 70 61 73 50 100
55 54 41 63 63 45 33 41 100
53 55 43 44 63 75 35 21 100
100 100 100 100 100 100 100 100 100
我工作的代码是这样的:
#! /bin/bash
clear
#the arguments below will check for your command line args whether you have provided corrctly or not
flag=0
if [ "$#" -eq 0 ]; then
echo "Please provide arguments"
elif [ "$#" -lt 2 ]; then
echo "You have to provide 2 arguments" >&2
exit 1
elif [ "$#" -gt 2 ]; then
echo "${#}"
FILE= "${4}"
if [ -f "${FILE}" ]; then
flag=1
else
echo "You have provided more number of arguments" >&2
fi
exit 1
else
echo "You have entered correct number of arguments"
fi
# the below code is the case code which checks whether you have -r/-rows or -c/-cols
option="${1}"
l1=0
sorted=()
case ${option} in
-rows| -r| -r*)
if [ $flag -eq 1 ]; then
FILE="${4}"
else
FILE="${2}"
fi
clear
echo "Average Median"
lines=$(wc -l < "$FILE")
while read -r line
do
len=0
tot=0
name=$line
#array=(`echo $name | cut -d " " --output-delimiter=" " -f 1-`)
IFS=' ' read -a array <<< "$name" #if any error comes that might be with this line just check the spaces in the speech marks they should be 4 spaces as it is checking for tabs
for element in "${array[@]}"
do
tot=$(expr $tot + $element)
#let tot+=$element #you can use this as well to get the totals
let len+=1
done
avg=($(printf "%.0f" $(echo "scale=2;$tot/$len" | bc)))
readarray -t sorted < <(for a in "${array[@]}"; do echo "$a"; done | sort)
no=`expr $len % 2`
if [ $no -eq 0 ]; then
mid=`expr $len / 2`
echo "$avg ${sorted[$mid]}"
else
if [ $lines -lt 2 ]; then
mid=`expr $len / 2`
echo "$avg ${sorted[$mid]}"
else
l1=`expr $len / 2`
mid=`expr $l1 + 1`
echo "$avg ${sorted[$mid]}"
fi
fi
unset "array[@]"
unset "sorted[@]"
done < "$FILE"
;;
-cols| -c| -c*)
if [ $flag -eq 1 ]; then
FILE="${4}"
else
FILE="${2}"
fi
#echo "cols"
#echo "File name is $FILE"
cols=$(head -1 "$FILE" | tr "\t" '\n' | wc -l)
lines=$(wc -l < "$FILE")
IFS=$'\t\n' read -d '' -r -a lins < "$FILE"
while read line;do
x=1
read -a array <<< "$line" ##Split the line by spaces
for element in "${!array[@]}"
do
row[${element}]=$((${row[${element}]}+${array[$element]})) ##For each column increment array variable by number in the column.
((x++))
done
done < "$FILE"
echo "Averages: "
for element in ${row[@]}
do
mean= printf "%.0f" $(echo "scale=2;$element/$lines" | bc) ##bc prints floating point numbers and then we round of using scale and .0f
echo -n "$mean "
done
printf "\n"
echo "Medians: "
for ((i=0;i<$cols;i++))
do
carr=()
for ((j=i;j<$lines * $cols;j=j+$cols))
do
carr+=(${lins[$j]})
done
IFS=$' \n' csort=($(sort <<<"${carr[*]}"))
no=`expr $lines % 2`
if [ $no -eq 0 ]; then
mid=`expr $lines / 2`
echo -n "${csort[$mid]} "
else
if [ $lines -lt 2 ]; then
mid=`expr $lines / 2`
echo -n "${csort[$mid]} "
else
l1=`expr $lines / 2`
mid=`expr $l1 + 1`
echo -n "${csort[$mid]} "
fi
fi
done <<<"$lins"
printf "\n"
;;
*)
echo "`basename ${0}`:usage: [-r|-rows rows] | [-c|-cols columns]"
exit 1 # Command to come out of the program with status 1
;;
esac
trap "echo ;exit" 1 2
您还可以在脚本中将文件重定向到 stdin:
# redirect FILE to stdin
exec 0<$FILE
# read from FILE
read VAR
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)