gpt4 book ai didi

linux - 如何在 shell 脚本中将文件作为标准输入传递

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:29:30 25 4
gpt4 key购买 nike

我有一个 bash 脚本,它可以像这样调用:./stats.sh -rows test_file

该程序主要计算行平均值和中位数以及列平均值和中位数。现在我想将文件作为标准输入传递给程序。但是当我运行这段代码时,它会打印出 "you have 2 provide 2 arguments" .我必须进行哪些更改才能使代码将标准输入作为文件。我的意思是说,如果我想运行脚本,我也可以通过这种方式运行它 ./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

最佳答案

您还可以在脚本中将文件重定向到标准输入:

# redirect FILE to stdin
exec 0<$FILE
# read from FILE
read VAR

关于linux - 如何在 shell 脚本中将文件作为标准输入传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29695444/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com