最近在学习shell脚本编写,把几个练习记录一下。包括grep,sed,awk,距离生日天数的计算,累加求和,文件操作和文本操作。
找到/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,使用awk
和sed
两种方式。要注意的是和直接输出不同,在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
简单用whoami
和pwd
即可
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
中的用户名称全部取出,并以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格式的语法得手动进行注释。脚本用熟练了就还好,还是得多练习。