用shell来写脚本

首先介绍一下shell的常用的内置变量

$0				脚本名字
$1,$2...		传入参数1,2...
$#				传入参数的个数(不包含$0)
$*,$@			传入的所有参数(以空号隔开),可以以数组使用
"$*"和"$@"		$*和$@只有加""时才有区分,"$*"将所有的参数认为是一个字符串,"$@"将每个参数都当成一个单独的字符串,可以当成数组使用
$?				上个命令的退出状态,或函数的返回值,可以判断上一条指令的执行结果
$$				脚本的进程ID(PID)

更详细请参考下文:
http://blog.csdn.net/u012749933/article/details/48030503

一.守护脚本

用于守护一个进程,如果该进程因意外情况停止运行,则守护脚本会自动启动该进程,以保证该进程一直处于运行状态中。
下面是用shell实现的一个守护脚本:

#! /bin/sh
#进程名字可修改
PRO_NAME=zhb-t
#程序启动脚本命令
START_SH="./start.sh"

#用ps获取$PRO_NAME进程数量
NUM=`ps aux | grep ${PRO_NAME} | grep -v grep |wc -l`
#echo $NUM
#少于1,重启进程
if [ "${NUM}" -lt "1" ];then
    echo "${PRO_NAME} has been killed"
    ${START_SH}
    echo "${PRO_NAME} started"
fi
exit 0

该脚本然后用crontab定时执行,监控进程是否停止

二. 杀死进程

kill某个进程名下所有进程

#! /bin/sh
#进程名字可修改
PRO_NAME=example_echocli

pidnum=`ps -ef|grep ${PRO_NAME} |grep -v grep|wc -l`
if [ $pidnum -lt 1 ]
then
	echo "no program killed."
else
	for pid in `ps -ef|grep ${PRO_NAME} |grep -v grep|awk '{print $2}'`
	do		
		kill -9 $pid
	done
	echo "program stoped."
fi
exit 0

或者更简单的是:

ps -ef | grep "procedure" | grep -v grep | awk '{print $2}' | xargs kill -9

三. admin工具

#!/bin/sh

RED=\\e[1m\\e[31m
DARKRED=\\e[31m
GREEN=\\e[1m\\e[32m
DARKGREEN=\\e[32m
BLUE=\\e[1m\\e[34m
DARKBLUE=\\e[34m
YELLOW=\\e[1m\\e[33m
DARKYELLOW=\\e[33m
MAGENTA=\\e[1m\\e[35m
DARKMAGENTA=\\e[35m
CYAN=\\e[1m\\e[36m
DARKCYAN=\\e[36m
RESET=\\e[m

if [ $# != 1 ]
then
	echo -e "$RED USAGE: $0 $YELLOW option [start | stop | restart]$RESET"
	exit 0;
fi


dir=`echo $0|sed 's/admin.sh//g'`
cd $dir

if [ $1 = "start" ]
then
    ./start.sh

elif [ $1 = "stop" ]
then
    ./stop.sh

elif [ $1 = "restart" ]
then
    ./stop.sh
    ./start.sh

else
	echo -e "$RED USAGE: $0 $YELLOW option [start | stop | restart]$RESET"
	exit 0;
fi

四.遍历文件夹,并判断文件后缀名

#!/bin/sh

PHPPATH="/root/zhb/php/pchart.1.27d/"
PHPBIN="/usr/local/php/bin/php -f"

filelist=`ls $PHPPATH`
for file in $filelist
do 
	if [ "${file##*.}" = "php" ]
	then
		$PHPBIN $PHPPATH/$file
	fi
done

五. shell操作redis和mysql

//删除redis的某个key
echo "del verify_0" | /export/servers/redis/redis-cli -h 192.22.144.34 -p 6379

//或者直接用redis-cli后面加参数执行
./redis-cli -p 6379 -a password config set timeout 600

//删除mysql的某张表数据
mysql -uroot -h192.168.144.121 -pmysql -e "truncate table test.myzhb"

六. 在shell脚本中执行带参数的sh文件

/bin/bash -c ./mybatch.sh param1 param2

注意加-c
或者用七的方法,echo ``

七. 批量转化IP

把一个十进制数转化为点分制ip的脚本

#!/bin/bash
N=$1
H1=$(($N & 0x000000ff))
H2=$((($N & 0x0000ff00) >> 8))
L1=$((($N & 0x00ff0000) >> 16))
L2=$((($N & 0xff000000) >> 24))
echo $H1.$H2.$L1.$L2

将上面的脚本保存为num2ip.sh
按行读取文本,批量转换(注意要要将每一行的最后一个换行符去掉):

#!/bin/bash
for line in `cat ./ip`
do
echo `./num2ip.sh ${line%?}`	#去掉最后一个字符\n
done

八. 文件操作

1. file,head,tail命令

file 2016.txt
head -2 2016.txt (前2行)
tail -10 2016.txt (最后10行)

2. 创建文件

vi zhb.txt
vi操作:
退出vi::wq,编辑::i
复制文件:cp -r src dst
删除文件/文件夹: rm -rf zhb.txt //彻底删除,慎用
新建文件夹:mkdir zhb
移动文件:mv zhb.txt /usr/zhb/
复制文件夹:cp -r src dest -r是递归复制文件夹中的文件

3.多个文件去重

有三种方法:

paste -d"\n" file1 file2 | sort | uniq > file3
cat file1 file2 | sort | uniq > file3
awk '!a[$0]++' file1 file2 file3

解释:

1、当条件 !a[$0]++ 为真时,awk 的默认动作是 print $0 ,即打印出当前行;
2、当一行首次出现时,a[$0] 为假,!a[$0]++ 为真。
以后,当相同的行再次出现时,a[$0] 为真,!a[$0]++ 为假,所以不再打印该重复的行。
所以就实现了去除重复行的功能。

4.提取一个文件的奇数行

类似上面的运用还有很多,比如提取一个文件的奇数行,可用如下方法:

awk 'NR%2' a.txt 

sed实现提取奇数行:

sed -n 'p;n'

注意:当对大文件合并时,前两种方法并不可靠,可能大文件无法载入内存,awk方法是最简单的,最高效的。(awk每次只载入一行)

5.多行合并为一行

cat ip_list | xargs
awk BEGIN{RS=EOF}'{gsub(/\n/,",");print}' ip_list

cat这条命令是直接将多行合并为一行,不加分隔符。
awk这条命令的作用是将每行的数据用逗号连接,合并为一行。
awk默认将记录分隔符(record separator即RS)设置为\n,此行代码将RS设置为EOF(文件结束),也就是把文件视为一个记录,然后通过gsub函数将\n替换成逗号,最后输出。

九.常用shell语句

1. 统计词频:

https://leetcode-cn.com/problems/word-frequency/

awk '{for(x=1;x<NF+1;x++){print $x}}' words.txt | sort| uniq -c | sort -k1nr | awk '{print $2,$1}'

2.转置文件

https://leetcode-cn.com/problems/transpose-file/

awk '{
    for (i=1;i<=NF;i++){
        if (NR==1){
            res[i]=$i
        }
        else{
            res[i]=res[i]" "$i
        }
    }
}END{
    for(j=1;j<=NF;j++){
        print res[j]
    }
}' file.txt

awk是一行一行地处理文本文件,运行流程是:

先运行BEGIN后的{Action},相当于表头
再运行{Action}中的文件处理主体命令
最后运行END后的{Action}中的命令
有几个经常用到的awk常量:NF是当前行的field字段数;NR是正在处理的当前行数。

注意到是转置,假如原始文本有m行n列(字段),那么转置后的文本应该有n行m列,即原始文本的每个字段都对应新文本的一行。我们可以用数组res来储存新文本,将新文本的每一行存为数组res的一个元素。

在END之前我们遍历file.txt的每一行,并做一个判断:在第一行时,每碰到一个字段就将其按顺序放在res数组中;从第二行开始起,每碰到一个字段就将其追加到对应元素的末尾(中间添加一个空格)。

文本处理完了,最后需要输出。在END后遍历数组,输出每一行。注意printf不会自动换行,而print会自动换行。

3. 输出第十行

https://leetcode-cn.com/problems/tenth-line/

awk 'NR == 10{print $0}' file.txt
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值