Linux实验 Shell程序设计
Posted _DiMinisH
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux实验 Shell程序设计相关的知识,希望对你有一定的参考价值。
Linux实验 Shell程序设计
1. 读取一个整数n,输出斐波那契数列的前n项及它们的和
问题分析
斐波那契数列,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:
F(0)=0,F(1)=1
F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
使用三个变量的方法计算,初始情况下:a1=1 a2=1 a3=0 sum=0
通过循环计算a3的值,并且更新a1和a2的值,每计算出一项,把新的项的值加入到sum中
程序代码
#!/bin/bash
# 存放第一个参数的值
num=$1
# 第一个数
a1=1
# 第二个数
a2=1
# 存放下一个数
a3=0
# 记录和
sum=2
# 如果没有输入参数,则直接结束脚本
if [ $# -eq 0 ]; then
exit 1
fi
# 如果输入的参数是1
if [ $num -eq 1 ]; then
# 输出斐波那契数列的第一项和和
echo -ne "fib:" $a1 "\\n"
echo -ne "sum:" 1 "\\n"
# 如果输入的参数是2
elif [ $num -eq 2 ]; then
# 输出斐波那契数列的第一项和和
echo -ne "fib:" $a1 " " $a2 "\\n"
echo -ne "sum:" 2 "\\n"
# 如果输入的参数是2以上的数字
else
echo -ne "fib:" $a1 " " $a2 " "
# for循环计算
for (( i=3; i<=$num; i++)) do
# 计算出下一个数
let a3=$a2+$a1
echo -n $a3 " "
# 把结果加入和中
let sum=$sum+$a3
let a1=$a2
let a2=$a3
done
echo -ne "\\nsum:" $sum "\\n"
fi
2. 读取若干输入,把第二个位置参数及其以后的各个参数指定的普通文件复制到第一个位置参数指定的目录中
若第一个参数指定的目录不存在,则创建它;若存在且为普通文件,则删除该文件,并创建为目录;若存在且为目录,则清空这个目录
第二个参数及其以后的参数,若为普通文件则复制到第一个参数指定的目录,否则忽略
问题分析
首先根据题目,判断第一个参数指定的目录的状态
测试 | 为ture的条件 |
---|---|
[ -e file ] | 文件存在 |
[ -d file ] | 文件存在,且为目录文件 |
[ -f file ] | 文件存在,且为普通文件 |
程序代码
#!/bin/bash
# 文件参数个数
parameter_number=$#
# 要移动到的文件路径
file_path=$1
# 没有任何参数
if [ $# -eq 0 ]; then
exit 1 # 退出
fi
# 如果第一个参数指定的目录不存在
if [ ! -d $file_path -a ! -f $file_path ]; then
mkdir $file_path # 创建目录
# 如果为普通文件
elif [ -f $file_path ]; then
rm -f $file_path # 删除它
mkdir $file_path # 创建目录
# 如果目录存在
elif [ -d $file_path ]; then
rm -f $file_path/* # 清空
fi if [ $# -gt 1 ]; then
# 循环复制文件到目录下面
for (( i=2; i <= $parameter_number; i++)); do
# 获取第二个未知参数的值,第二个位置开始,是要移动的文件
file_name=$2
# 判断该文件是不是普通文件
if [ -f $file_name ]; then
# 如果是就移动
mv "$file_name" "$file_path/"
fi
# 将每个位置参数的值向前挪一个
shift
done
fi
3. 读取/etc目录下的所有普通文件,寻找其中最长的一行,输出其内容和长度(忽略/etc的所有子目录)
问题分析
通过ls命令,可以列出/etc目录下的所有文件的名字,将ls命令的结果作为while循环中的输入条件,即从结果中一条一条的取数据,如果这个数据是普通文件,就计算出长度和记录下字符串,提前设置一个长度最大值变量和记录最大长度字符串的变量,比较计算出的长度和长度的最大值,如果最大值小于当前的长度,就更新最大值和字符串
程序代码
#!/bin/bash
# 用来存放最大长度的变量
maxLength=0
# 用来存放最大字符串的变量
maxString=""
# 将ls结果作为输入, 依次放入到line中
ls /etc | while read line; do
# 文件在/etc目录下,所有要加入父目录,否则是当前目录的文件
path="/etc/$line"
# 如果这个文件是普通文件
if [ -f $path ]; then
# length中存放每一条记录的长度
length=$#line
# 如果当前记录的长度大于最大记录的长度
if [ $length -gt $maxLength ]; then
# 改变最大长度和最大字符串
let maxLength=$length
maxString=$line
# 将maxString的内容重定向到(写到)一个tp文件中
# tp不存在就创建,存在就覆盖
# tp文件用来存放记录下来的最大字符串和长度
echo $maxString > tp
# 追加写入
echo -n "长度:" >> tp
# 追加写入
echo $maxLength >> tp
fi
fi
done
echo /etc下最长文件是:
# 输出tp文件的内容
cat < tp
# 删除tp文件
rm tp
4. 依次读取年、月、日三个参数(如1991 2 14),计算它距离今天的天数。
能被4整除但不能被100整除,或能被400整除的年为闰年
使用date +”%-Y”,date +”%-m”和date +”%-d”可获得当前的年月日
问题分析
计算两个时间之间的天数,可以从年份、月份、天数依次比较
首先,年份和月份一样,天数作差即可
其次,年份相同,月份不同,计算相差的月份,把相差的完整的月份的天数计算出来,再计算不完整的天数
最后,年份不同月份不同,还是计算完整月份的天数,还要计算完整年份的天数,最后把这些天数和不完整的天数加在一起,就能得到最后的相差的天数
程序代码
#!/bin/bash
# 如果输入的参数不是3个
if [ ! $# -eq 3 ]; then
# 直接退出
exit 1
fi
# 记录差
dayGap=0
monthGap=0
yearGap=0
# 获取当前日期
currentTime=`date +%Y-%m-%d`
# 提取年月日 2021-12-19
year=$currentTime:0:4
month=$currentTime:5:2
day=$currentTime:8:2
# echo $year $month $day
# 判断一年是否是闰年
function isLeapYear ()
t=$1
let prv=$t%4
let nxt=$t%100
let aft=$t%400
if [ $prv -eq 0 -a ! $nxt -eq 0 -o $aft -eq 0 ]; then
echo 1
else
echo 0
fi
function Month ()
pMonth=$1
pYear=$2
pDay=0
provisional=`isLeapYear $pYear` # echo "provisional=$provisional $pYear" >> tp
if [ $provisional -eq 1 ]; then
case $pMonth in
1) pDay=31;;
2) pDay=29;;
3) pDay=31;;
5) pDay=31;;
7) pDay=31;;
8) pDay=31;;
10) pDay=31;;
12) pDay=31;;
*) pDay=30;;
esac
else
case $pMonth in
1) pDay=31;;
2) pDay=28;;
3) pDay=31;;
5) pDay=31;;
7) pDay=31;;
8) pDay=31;;
10) pDay=31;;
12) pDay=31;;
*) pDay=30;;
esac
fi
echo $pDay
function yearDay ()
dd=0
provision=$1
for ((i=1; i<=12; i++)); do
let c=`Month $i $provision` # echo $c >> temp
let dd=$dd+$c # echo "dd=$dd" >> temp
done
echo $dd
# 获取输入日期
inputYear=$1
inputMonth=$2
inputDay=$3 # echo $inputYear $inputMonth $inputDay
# 两个日期在同一年
if [ $year -eq $inputYear ]; then
# 同一个月
if [ $inputMonth -eq $month ]; then
let dayGap=$day-$inputDay
# 不同月
else
provisionalYear=$inputYear
let monthGap=$month-$inputMonth
let $monthGap=$monthGap-1
for (( i=$monthGap; i>0; i--)); do
let temp=$inputMonth+$i
let dayGap=$dayGap+`Month $temp $provisionalYear`
done
a=`Month $inputMonth $provisionalYear`
let a=$a-$inputDay
let dayGap=$dayGap+$a
let dayGap=$dayGap+$day
fi
# 不同年
else
# 计算输入年份和现在年份之间空白年的总天数
let yearGap=$year-$inputYear # echo "yearGap=$yearGap" >> temp
for ((i=$yearGap-1; i>0; i--)); do
let provisionalYear=$inputYear+$i # echo "provisionalYear=$provisionalYear" >> temp
for ((j=1; j<=12; j++)); do
a=`Month $j $p provisionalYear`
let dayGap=$dayGap+$a
done
done
# 计算现在年份还有多少天
provisionalYear=$year
for ((i=1; i<$month; i++)); do
let a=`Month $i $provisionalYear`
let dayGap=$dayGap+$a
# echo "dayGap=$dayGap" >> temp
done
let dayGap=$dayGap+$day
# 计算输入年剩余天数
provisionalYear=$inputYear
a=0
for ((i=1; i<$inputMonth; i++)); do
let b=`Month $i $provisionalYear`
let a=$a+$b # echo "dd1=$a" >> temp
done
let a=$a+$inputDay
let b=`yearDay $inputYear` # echo $b
let b=$b-$a
let dayGap=$dayGap+$b
fi
echo "相距$dayGap天"
以上是关于Linux实验 Shell程序设计的主要内容,如果未能解决你的问题,请参考以下文章
合肥工业大学Linux实验三Linux 下的 shell 编程
合肥工业大学Linux实验三Linux 下的 shell 编程