几个常用的 shell 模板
程序员文章站
2022-06-29 12:54:11
...
去掉文本中的 BOM
utf-8 还有 utf-8 with bom 的格式,如果是这种格式的话,
在执行
hive -f file.sql 的时候,会报错。
单个文本的情况下,可以使用下面的方法:
使用 set nobomb 命令
:set nobomb
:x
批量更改的命令:
ls *.sql | xargs sed 's/\xef\xbb\xbf//g'
使用 presto 命令文件
grep -R 'presto-client' ./* | awk -F: -v OFS="---" '{print $1,$2}' | sed 's/--catalog.*//g; s/num=`//g' > ~/presto.txt
批量 explain
#!/bin/bash -x
sql_file_path=$1
temp_path=$(mktemp -t -d explain_XXXXX)
cp $sql_file_path/*.sql $temp_path/
cd $temp_path
for file in `ls $temp_path/*.sql`
do
sed -i 's/\;/\n\;/g' $file
csplit $file /\;/ -s {*} -n2 -f 'split' -b "%02d.sql"
for f in `ls $temp_path/split*.sql`
do
sed -i "1i explain " $f
sed -i " s/\;//g" $f
[ `grep "select" $f | wc -l` -gt 0 ] && hive -f $f
# rm -f $f
done
if [ "$?" -eq 0 ]; then
echo "$file has synopsis error"
exit 1
fi
exit 0
done
取出可见字符
sed -i " /^$/d ; s/[[:space:]]//g" split02.sql
--删除行首空格
sed 's/^[ \t]*//g'
删除历史的数据
find $curr_dir/ -name '*.txt' -ctime +7 -exec rm -f {} \;
UUID
cat /proc/sys/kernel/random/uuid
进程的管理
//https://www.cnblogs.com/itech/archive/2012/09/16/2687404.html
nohup command args // 忽略所有的hangup信号 ,ssh 后的 exit logout 断网都属于 hangup
setsid
jobs -l 查看后台进程
通过以下命令,我们可以对放入到后台的命令进行控制
查看当前终端下的后台进程:
直接执行:jobs
将查看到的某个后台进程放回到前台:
直接输入:fg {jobid} //这里的{jobid}是通过jobs命令中看到的进程前[]中的数字。
将当前正在前台运行的进程放到后台运行:
先敲下快捷键:ctrl +z //暂停当前正在运行的进程。
再执行:bg
终止当前正在前台运行的进程:
直接敲下快捷键:ctrl +c
disown亡羊补牢,为没有使用nohup与setsid的进程加上忽略HUP信号的功能。
使用方法:
将当前正在前台运行的进程放到后台运行(ctrl+z和bg);
然后执行disown -h %{jobid} //这里的{jobid}是通过jobs命令中看到的 进程前[]中的数字。
执行历史命令
!-{prefix-word}
例如:
!-his : 执行匹配的以 his 开头命令
sort 命令的应用
cat /etc/passwd | sort -k3 -t : | head -2
-k 是关键词,类比, -k1 --> order by 1
-t seperate , 例如 , -t : --> 使用 : 分割符号
不退出 .sh 文件,执行 .sh
1. shift + ;
2. :!bash -x %
3. :r !ls *.sql -- 取出当前目录下 sql 文件的名字放到当前行
其中 % 就是代表了当前的 shell 文件
如何生成临时文件
生成独一无二的文件名称的场景下,我们可以是使用 $$ 就可以了,例如 sed expression file > file$$
正如 shell 中,只要你想不到,没有做不到。 shell 有一个的维护临时文件的命令:
mktemp -[ d | t] sql_XXXXXX.sql
d:是临时目录
t:在系统默认的临时文件的路径写新建文件,一般是 /tmp/
XXXXX 是站位符,mktemp 会给我们自动生成几个符号
egrep 的应用
cat log.log | egrep '任务启动时刻|任务结束时刻|任务总计耗时|任务平均流量|记录写入速度|读出记录总数|读写失败总数' | xargs echo | awk '{print "\""$20"\",\""$23"\""}' | sed 's/"//g' | cut -d ',' -f 1
wordCount
[[email protected] ~]# cat d.txt
db.t1
db2.t2
aaa aaa
aaa
aaa
aaa
aaa
aaa
[[email protected] ~]# cat d.txt | tr ' ' '\n' | uniq -c
1 db.t1
1 db2.t2
7 aaa
cat work.txt
cat work.txt | tr ' ' '\n' | awk 'BEGIN{print "word","count"} \
{rs[$1]++} \
END{for(i in rs ){print i,rs[i]}}\
'
cat work.txt | awk 'BEGIN{print "word","count"} \
{for(i=0;i<=NF;i++){rs[$i]++}}
END{for(i in rs ){print i,rs[i]}}\
'
先整理一下 awk 的通用格式
awk [-f] [-F] [-v] [-FS] [-OFS] 'BEGIN{expresion} row_filter_regexp_expression {action} END{expression}'
BEGIN:在遍历每一行之前做的操作
END:遍历完每一行之后做的操作
row_filter_regexp_expression:使用正则表达式,或者逻辑表达式来过过滤行,相当于 where
{action} 处理里面的每一行,就会 select 一样
多行合并
sed ':a ; N;s/\n/ / ; t a ; ' file
通常的认为下面会 sed 会替换没一行上的回车,但是不会,如果要想替换回车,需要 tr '\n' ''
tr --> translate
[[email protected] ~]# cat d.txt | sed 's/\n//g '
db.t1
db2.t2
aaa
aaa
aaa
aaa
aaa
aaa
[[email protected] ~]# cat d.txt | sed ' N ;s/\n/,/g '
db.t1,db2.t2
aaa,aaa
aaa,aaa
aaa,aaa
[[email protected] ~]# cat d.txt | sed ':a ; N ;s/\n/,/g ; t a '
db.t1,db2.t2,aaa,aaa,aaa,aaa,aaa,aaa
最简单的:
cat d.txt | xargs
使用 sed 替换,
为\t
cat file | sed "s#,#\t#g"
查看主机上所有的 git repository 已经状态
find ~ -name ".git" 2> /dev/null | sed 's/\/.git/\//g' | awk '{print "-------------------------\n\033[1;32mGit Repo:\033[0m " $1; system("git --git-dir="$1".git --work-tree="$1" status")}'
刷新历史数据的例子
// example.sh 20190501 20190531
// 数据从 20190501 刷新到 20190531
#!/bin/bash -x
start=${1:?please input start_date}
end=${2:?please input end_date}
i=0
while [ ${start} -le $end ]
do
bash -x wyf.sh $start
start=$(date -d " $start 1 day " +%Y-%m-%d)
i=$(($i+1))
done
// 传入的参数是 example.sh 1
// 这个意思是从从昨天,往前刷新 1 天的数据
#/bin/bash -x
for (( i = 1; i <= $1; i++ )); do
date=$(date -d"-$i day" +%Y-%m-%d)
echo $date
bash -x run_all.sh $date $date
done
#!/bin/bash -x
start=${1:?please input start_date}
end=${2:?please input end_date}
while [ `date -d ${start} +%s` -le `date -d "$end" +%s` ]
do
bash -x $3 $start
start=$(date -d"${start} -1 day" +%Y-%m-%d)
done
show ip
ifconfig | awk '$1="inet" && $2 ~ /addr:[0-9]+/ {print $2}' | awk -F ':' ' $2 != "127.0.0.1" {print $2}'
ifconfig | awk '$1="inet" && $2 ~ /[0-9]{2,3}\.[0-9]{2,3}\.[0-9]{2,3}\.[0-9]{2,3}/ {print $2}'
show diretory like tree
ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'
查看连接你服务器 top10 用户端的 IP 地址
netstat -nat | awk '{print $5}' | awk -F ':' '{print $1}' | sort | uniq -c | sort -rn | head -n 10
随机产生 32 的密码
tr -dc '[email protected]#$%^&*_()+}{?></";.,[]=-' < /dev/urandom | fold -w 32 | head -n 1
多行数据合成一行
ls *.sh | awk '{print NR":/data/app/product/yc_data/workflow/biz/dm/deliver/dm_deliver/"$1}' | sed ':a;N;$!ba;s/\n/;/g'
取文本中的某个值
tail -100 his_out.log | grep '读出记录总数' | cut -d ':' -f 2 | sed s/' '//g
日期
#!/bin/bash -x
today=${1:-`date -d " -1 day " +%Y%m%d `}
## the first day of last month
first_day=$(date +%Y%m )01
## the first day of this month
last_month_first_day=$(date -d " -1 month" +%Y%m )01
## the fist day of the month` the first day
week=`date -d "$first_day" +%w`
if [ $week -eq 0 ] ; then
week=7
fi
((week--))
monday=`date -d " ${first_day} -${week} days" +%Y%m%d`
week=`date -d "$last_month_first_day " +%w`
if [ $week -eq 0 ] ; then
week=7
fi
((week--))
last_month_monday=`date -d " ${last_month_first_day} -${week} days" +%Y%m%d`
week=`date -d "$today" +%w`
if [ $week -eq 0 ] ; then
week=7
fi
((week--))
## 本周星期一的日期
monday=`date -d " ${today} -${week} days" +%Y%m%d`
## 本周星期日的日期
sunday=`date -d " ${monday} +6 days" +%Y%m%d`
## 上周星期一的日期
last_week_monday=`date -d " ${monday} -7 days" +%Y%m%d`
## 上周星期天的日期
last_week_sunday=`date -d " ${sunday} -7 days" +%Y%m%d`
上一篇: 几个常用的小shell
下一篇: 常用的几个lodash函数