shell练习(grep,sed,awk,距离生日天数的计算,累加求和,文件操作和文本操作)

最近在学习shell脚本编写,把几个练习记录一下。包括grep,sed,awk,距离生日天数的计算,累加求和,文件操作和文本操作。

grep相关练习

找到/huiluczp下含有星号的文件与内容,主要是利用find来找到所有待查的文件作为参数给grep

echo '找到/huiluczp下含有星号的文件与内容'
grep '\*' $( find /home/huiluczp/huiluczp -type f )

找到所有目录下所有含有星号的文件名,并使用xargs来进行优化。太长的命令无法执行,使用xargs每十个文件执行一次。

echo 'xargs优化查询'
find /home/huiluczp -type f | xargs -n 10 grep -l '\*'

设置myip新命令来拿到本机的ip,使用awksed两种方式。要注意的是和直接输出不同,在alias的时候awk需要对$进行转义。sed的主要思路是将ip字段前后的字符串全部变为空,即可得到ip字段。

ifconfig eth0 | grep 'inet ' | awk '{print $2}'
alias myip="ifconfig eth0 | grep 'inet ' | sed 's/^.*inet //g' | sed 's/ *netmask.*$//g'"
myip
alias myipawk="ifconfig eth0 | grep 'inet ' | awk '{print \$2}'"
myipawk

/home/huiluczp下面只要含有XYZ字符中的任何一个字符就列出来,简单正则使用。

grep '[XYZ]' $( find /home/huiluczp -type f )

去除开头为#的行,去除空白行,取出开头为英文的行,统计最终行数。对行做处理sed比较方便。

cat /home/huiluczp/huiluczp/text.txt | sed 's/^#.*$//g'
cat /home/huiluczp/huiluczp/text.txt | sed 's/^#.*$//g' | sed 's/\n//g' | sed '/^$/d'
cat /home/huiluczp/huiluczp/text.txt | sed 's/^#.*$//g' | sed 's/\n//g' | sed '/^$/d' | grep '^[A-Z,a-z]'
cat /home/huiluczp/huiluczp/text.txt | sed 's/^#.*$//g' | sed 's/\n//g' | sed '/^$/d' | grep '^[A-Z,a-z]' | wc -l

输出目前身份和当前目录

简单用whoamipwd即可

echo "当前身份为:$(whoami)"
echo "当前目录为:$(pwd)"

计算离生日还有几天

首先read用户输入,并利用正则去判断生日输入格式的正确性。

#!/bin/bash

# 输入生日日期
read -p "输入生日日期, 格式为mm-dd:" birthday
echo ${birthday}

# 简单判断是否为dd-dd格式
check_date=$( echo ${birthday} | grep '[0-9]\{2\}-[0-9]\{2\}' )
if [ -z check_date ];
    then
        echo "格式错误"
        exit 1
fi

考虑特殊情况,利用date拼接当天日期,字符串相同直接输出

# 特殊情况,如果正好是当天,那么输出提示
if [ "$(date +%m)-$(date +%d)" == "${birthday}" ];
    then
        echo "今天就是生日!"
        exit 1
fi

利用%s获取秒数,--date参数中将生日和当前年份进行组合,得到今年生日和今天间的秒数差值。

# 计算日期,如果当年还未到,那么直接取差值
date_now=$(date +%s)
year_now=$(date +%Y)
date_birthday=$(date --date="${year_now}-${birthday}" +%s)
date_diff=$((${date_birthday}-${date_now}))

echo ${date_diff}

考虑今年生日过了与否,通过秒数差值进行计算。当今年生日已过时,year+1计算下一年的生日和今天的差值。

if [ "${date_diff}" -lt "0" ];
    then 
        date_birthday=$(date --date="$((${year_now}+1))-${birthday}" +%s)
        date_diff=$((${date_birthday}-${date_now}))
        # echo ${date_diff}
fi

最后利用秒数转成天数,注意向上+1。

# 将差值转换为天数
remain_day=$((${date_diff}/24/60/60))
echo "当前时间为: $(date +%Y)-$(date +%m)-$(date +%d)"
# 有小数向上
echo "离下次生日还剩$((${remain_day}+1))天"
exit 0

累加求和

用户输入数字进行循环累加。简化了没进行数字合法性判断。

#!/bin/bash

read -p '输入一个大于1的数字:' input_num

sum=0
for (( i=1; i<=${input_num}; i=i+1 ))
do
    sum=$((${sum}+${i}))
done

echo "最后结果为${sum}"
exit 0

文件操作

判断是否存在,不存在则创建文件;存在且为目录文件,删除。存在且为文件,删除后创建同名目录。主要是判断式,删除命令和创建命令的使用。

#!/bin/bash

file_name=/home/huiluczp/huiluczp/logical

# 判断是否有/home/huiluczp/huiluczp/logical存在
if [ ! -e "${file_name}" ];
then
    # 不存在则创建文件
    echo "创建文件${file_name}"
    touch ${file_name}
else
    # 存在且为file,则删除后创建目录
    if [ -f "${file_name}" ];
    then
        echo "存在文件${file_name}, 删除后创建目录"
        rm ${file_name}
        echo "${file_name}文件已删除"
        mkdir ${file_name}
        echo "${file_name}目录已创建"
    # 存在且为dir,删除目录
    elif [ -d "${file_name}" ]
    then 
        echo "存在目录${file_name}, 删除该目录"
        rmdir ${file_name}
    fi
fi
exit 0

文本操作 /etc/passwd

/etc/passwd中的用户名称全部取出,并以The <行号> account is <用户名>的格式进行输出。用awk并且搭配FS(间隔符)和NR(行号)能比较方便地进行处理。

#!/bin/bash

pass_file=/etc/passwd

# 将文件中的第一行拿出来,转成The ${line_num} account is ${user}
cat pass_file | awk 'BEGIN {FS=":"} {print "The",NR,"account is",$1}'

总结

shell脚本写起来有些语法挺别扭的,包括各种引号的使用,转义字符等,调了还蛮久。还有就是ubuntu默认shell不是bash,所以要用c格式的语法得手动进行注释。脚本用熟练了就还好,还是得多练习。

你可能感兴趣的:(linux,linux,服务器,shell)