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
	#	echo $path
		# 读取文件中的信息
		cat $path | while read content; do
			# length中存放每一条记录的长度
			length=${#content}
			# 如果当前记录的长度大于最大记录的长度
			if [ $length -gt $maxLength ]; then
				# 改变最大长度和最大字符串
				let maxLength=$length
				maxString=$content
				# 将maxString的内容重定向到(写到)一个tp文件中
				# tp不存在就创建,存在就覆盖
				# tp文件用来存放记录下来的最大字符串和长度
				echo $maxString > tp
				# 追加写入
				echo -n "长度:" >> tp
				# 追加写入
				echo $maxLength >> tp
			fi
		done;
		
	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天"
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值