这里收藏工作中用到的脚本,也为了防止做重复的搜索工作,同时分享给大家。
数组
初始化数组
1
2
3name = (value1 value2 ... valuen)
A=(a b c d)
echo ${A[@]} # 输出所有元素数组去重
1
array=($(awk -vRS=' ' '!a[$1]++' <<< ${array[@]}))
取得数组元素的个数
1
echo ${#A[@]}
取下标
1
echo ${A[1]} # 从1开始
清除元素
1
2unset A
echo ${A[@]}循环取元素
1
2
3for a in ${A[@]}; do
echo "$a"
done替换
1
${A[@]/3/100}
date
获取当前日期并格式化成指定格式
1
NOW=$(date +'%Y-%m-%d_%H%M%S') # 2016-09-07_184914
获取一个小时前的日期
1
date --date="1 hours ago" +"%Y-%m-%d"
字符串转日期
1
2date -d '2019-05-20'
date -d '2019-05-20' +%s #转成时间戳计算当前时间的时间戳
1
STAMP=$(($(date +%s -d "$(date +'%Y-%m-%d %H:%M:%S')"))) # 1473245414
计算N天之前的时间
1
2十天之前的日期
TEN_DAYS_AGO=$(($(date -d '-10 day' "+%Y%m%d%H%M%S"))) #20160828185138计算指定日期的前一天
1
date -d "2019-05-20 -1 day" +"%Y%m%d"
获取指定日期的季度
1
2
3
4SEASON=`echo "${today}" | awk -F "-" '{print $2}'| awk '{season_least=$1%3} {season=$1/3} {if(season_least>0) season+=1} {printf("%d\n",season)}'`
YEAR=`echo "${today}" | awk -F "-" '{print $1}'`
YEAR_SEASON="${YEAR}Q${SEASON}"
echo "YEAR_SEASON=${YEAR_SEASON}"获取xxxx年xx月的天数
1
2获取 2016-10 的天数
cal 10 2016 | awk 'NF{out=$NF;}END{print out}'
输出
1 | 31 |
vim
- vi/vim修改只读(readonly)文件,使用sudo修改
1
:w !sudo tee % > /dev/null
awk
过滤数字
1
echo "123" |awk '{if($0 ~ /^[0-9]+$/) print $0;}'
数字求和
1
cat ${FILE} | awk '{sum += $1};END {printf ("%d\n", sum)}'
截取字符串
1
echo "123456" | awk '{print substr($1,1,4)}' #1234
获取月份所在季度
1
for q in `seq 1 12`; echo $q | awk '{season_least=$1%3} {season=$1/3} {if(season_least>0) season+=1} {printf("%d\n",season)}'
输出
1 | 1 |
- 删除所有空格
1
echo "1 2 3 4" | sed -e 's/[[:space:]]//g '
输出
1 | 1234 |
- 替换所有的.为/
1
echo "com.xiongyingqi.Test" | awk '{gsub(/\./,"/"); print $0}'
输出
1 | com/xiongyingqi/Test |
sed
去除首尾空格
1
FOO_NO_EXTERNAL_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
删除空行
1
sed '/^$/d' sources.list
uniq
- 统计重复数
1
cat file | uniq -c
文件
寻找有指定内容的文件
1
2FOUND="test" # 需要查找的内容
find . | while read file; do if [ -f $file ]; then content=`cat ${file} | grep "${FOUND}"`; if [ -n "$content" ]; then echo ${file} ; fi; fi; done列举文件并用管道打包
1
find . -name "*.class" | xargs tar cvf classes.tar
变量
我们先写一个简单的脚本,执行以后再解释各个变量的意义
1 | touch variable |
脚本内容如下:
1 | !/bin/sh |
保存退出
赋予脚本执行权限
1 | chmod +x variable |
执行脚本
1 | ./variable aa bb |
输出
1 | number:2 |
通过显示结果可以看到:
- $# 是传给脚本的参数个数
- $0 是脚本本身的名字
- $1 是传递给该shell脚本的第一个参数
- $2 是传递给该shell脚本的第二个参数
- $@ 是传给脚本的所有参数的列表
- $* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
- $$ 是脚本运行的当前进程ID号
- $? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误
例子
- *amount.txt 下所有文件的第8列数字之和
iconv -fgbk 为转换文件为 gbk
1 | ls *amount.txt | while read file; do cat ${file}; done | iconv -fgbk | awk -F "\t" '{print $8}' | awk '{if($0 ~ /^[0-9]+$/) print $0;}' | awk '{sum += $1};END {printf ("%d\n", sum)}' |
- 将目录下的jar文件转换为maven格式的依赖
1 |
|
- 查找java类所在当前目录内的jar包
1 | FOUND="com.xiongyingqi.Test" && ls *.jar | while read jar; do jar tf $jar | grep `echo "${FOUND}" | awk '{gsub(/\./,"/"); print $0}'` | awk -v jar="$jar" '{if (length($1) > 0) print jar}'; done |
将目录内的文件转换为classpath需要的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15ls lib/*.jar | xargs | awk -v d="${delete}" '{
str="";
is_in=0;
for(i=1;i<=NF;i++){
if($i!=d){
if(is_in == 1){
str=str":"$i;
}else{
str=str""$i;
is_in=1;
}
}
}
print str
}'查找某个目录下所有的jar包里面有哪些class是冲突的shell脚本
1 | !bin/bash |
- 替换字符串
1 | data="a" && newdata="c" && echo "aaabbba"|awk -v var=${1} -v var1=${data} -v var2=${newdata} '$0 ~ var {gsub(var1,var2); print}' |
输出
1 | cccbbbc |
- 文件内容替换
替换当前目录下的所有文件
内容中的hello
为helloworld
1 | find . -type f | while read file; do sed -i 's/hello/helloworld/g' $file;done |
- 测试curl
1 | size=1000;i=0; while [ $i -lt $size ];do i=$((i+1)); curl "http://baidu.com" & done |
- 获取从开始日期到结束日期所经历过的季度
1 | FROM_DATE="$1" |
- 多线程访问
1 | for ((i=0;i<10;)); do |
- 按列合并
1 | cat filtsoort | awk '{sum[$1]+=$2}END{for (i in sum) print i" "sum[i]}' |
- 转换编码
1 | find . -name "*.java" | while read file; do iconv -f gbk -t utf-8 $file > ${file}.bak; mv -f ${file}.bak $file; done |
word转换为markdown
需要先安装w2m
: benbalter/word-to-markdown1
2
3
4
5
6
7find doc -name "*.doc" | while read file; do
folder_tmp="markdown/$file";
folder=${folder_tmp%/*};
target_file="${folder_tmp%%.*}".md
mkdir -p $folder;
w2m $file > $target_file;
done移除base64图像
1
sed -i 's-\!\[\](data:image\/\*;base64,.*)--g' $file
判断是否为asccii字符串(英文字符)
1
echo "呵呵" | awk '{ print (length($0)>NF)}' #1
输出带颜色的字符
shell脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e
格式如下:
1 | echo -e "\033[字背景颜色;文字颜色m字符串\033[0m" |
例如:
1 | echo -e "\033[41;36m something here \033[0m" |
其中41的位置代表底色, 36的位置是代表字的颜色
注:
1、字背景颜色和文字颜色之间是英文的””
2、文字颜色后面有个m
3、字符串前后可以没有空格,如果有的话,输出也是同样有空格
下面是相应的字和背景颜色,可以自己来尝试找出不同颜色搭配
例
1 | echo -e "\033[31m 红色字 \033[0m" |
字颜色:30—–37
1 | echo -e "\033[30m 黑色字 \033[0m" |
字背景颜色范围:40—–47
1 | echo -e "\033[40;37m 黑底白字 \033[0m" |
最后面控制选项说明
- \33[0m 关闭所有属性
- \33[1m 设置高亮度
- \33[4m 下划线
- \33[5m 闪烁
- \33[7m 反显
- \33[8m 消隐
- \33[30m — \33[37m 设置前景色
- \33[40m — \33[47m 设置背景色
- \33[nA 光标上移n行
- \33[nB 光标下移n行
- \33[nC 光标右移n行
- \33[nD 光标左移n行
- \33[y;xH设置光标位置
- \33[2J 清屏
- \33[K 清除从光标到行尾的内容
- \33[s 保存光标位置
- \33[u 恢复光标位置
- \33[?25l 隐藏光标
- \33[?25h 显示光标
1 | function echoGreen(){ |
- 从第二行开始显示
1
cat file | awk 'NR>2{print p}{p=$0}'
批量导出db数据
1 | for y in `seq 2015 2025`; do |
获取被执行脚本所在路径
1 | cur_script_dir="`cd $(dirname $0) && pwd`" |
awk获取第1列之后的列值
1 | awk '{ $1=""; print $0 }' ur_file |
另外, 如果我要打印某列以后的所有列的, 可以使用循环把, 把前N列都赋值为空:
1 | awk '{ for(i=1; i<=2; i++){ $i="" }; print $0 }' urfile |