Linux shell常用指令
0 前言
本人由于常在Linux中跑各种实验测试,为了减少精力,通常是先写好自动跑实验的脚本以及结果处理的脚本,最后直接用excel打开实验结果。为了方便读者以及自己以后写脚本,特总结了写shell脚本常用的指令。如有不当之处或者好的建议以及好的补充,欢迎各位读者在评论中指出,本人在此提前道声谢谢!
1 文本内容替换与删除
- 替换特定行的内容。 将hello.txt文件的第${line}行中的内容替换为sudo bash -c ‘echo 0 > /sys/kernel/mm/ksm/run’。注:${line}是提前定义的变量,可以直接固定为某数字,比3c表示第3行。-i表示替换文本
sed -i "${line}c sudo bash -c 'echo 0 > /sys/kernel/mm/ksm/run'" hello.txt
- 替换以特定字符开头的某一行。 比将hello.txt文件中所有以hibench.scale.profile的内容替换为"hibench.scale.profile ${var}",${var}是一个变量
sed -i "/^hibench.scale.profile/c\hibench.scale.profile ${var}" hello.txt
- 替换第一次出现的某字符。 比如将第一次出现${character}替换为${other_character},注意${other_character}和${character}都是shell变量,$/s中的$表示字符串结束。
sed -i "0,/${character}$/s/${character}$/${other_character}/g" hello.txt
- 在文件第一行之前添加内容。 比如将"hello world"添加到hello.txt第一行之前,其中
1i表示第一行。
sed -i "1i\hello world" hello.txt
- 删除文件第一列。
sed -i -e "s/[^ ]* //" hello.txt
- 删除文件第一行。 其中
1d表示第一行,nd表示第n行,$d表示最后一行。
sed -i '1d' hello.txt
2 行列选择
- 打印文件的第3行到第6行的第2列 (包含第3行和第6行)
cat test.txt | sed -n "3, 6p" | awk '{print $2}'
3 脚本参数处理
- 字符串分割或者替换。 比如用target_str替换source_str,比如使用
${str//,/ }可以将输入的字符串参数转换成数组,注意:字符串最好是"A B C"或者“A,B,C”或“A-B-C”这个样式的。
${parameter//source_str/target_str} #用target_str来替换parameter变量中所有匹配的source_str
- 打印帮助信息
read -r -d '' USAGE << EOS
Usage: $0 [options]
Options:
args parameter meaning and value
-h | --help Display help infomation.
-s | --scale Data scale profile. Available value is tiny, small, large, huge, gigantic and bigdata. Default value is small.
-m | --maps Mapper number in hadoop, partition number in Spark. Default value is 8.
-f | --shuffles Reducer nubmer in hadoop, shuffle partition number in Spark. Default value is 8.
-S | --spark-master Spark master. Standalone mode: spark://xxx:7077, YARN mode: yarn-client. Default value is yarn-client.
-n | --exec-num Spark executor number when running on Yarn. Default value is 2.
-c | --exec-cores Spark executor number when running on Yarn. Default value is 4.
-M | --exec-mem Spark executor memory in standalone & YARN mode. Default value is 4g.
-d | --driver-mem Spark dirver memory in standalone & YARN mode. Default value is 4g.
-b | --benchmark HiBench benchmark, available value is: micro.sleep, micro.sort, micro.terasort, micro.wordcount, micro.repartition, micro.dfsioe, sql.aggregation, sql.join, sql.scan, websearch.nutchindexing, websearch.pagerank, ml.bayes, ml.kmeans, ml.lr, ml.als, ml.pca, ml.gbt, ml.rf, ml.svd, ml.linear, ml.lda, ml.svm.
-p | --platform Which platform to run the benchmark, available value is hadoop, spark.
-D | --data-size Benchmark data size. Default value is determined by data scale. If data scale and data size are set at the same time, the value of data size will be updated. The unit of data size is byte.
EOS
上述代码实际上定义了帮助信息为USAGE这个变量,通过echo $USAGE即可输出信息(以Usage开始并以EOS结束的中间这段内容。)
- 根据参数执行相应的指令。 紧接着上面的“打印帮助信息”,并且假设用户执行脚本并且跟了一堆参数,则这一步需要解析用户参数并执行相应的指令。实际上,脚本参数处理有多种,比如使用
getopt或getopts函数,下面我们以getopt函数为例。
# 下面一行是执行getopt指令,其中-o表示短选项(即./my_shell.sh -h这种形式的命令),冒号表示某一个参
# 数后面需要跟参数值,比如--help/-h(即显示帮助指令)不用 跟参数值,所以h后面就没有冒号,而scale表
# 示规模,需要有一个具体的值,所以s后面要有冒号。而--long表示长选项(即./my_shell.sh --help这种
# 形式的命令)。-n表示出错时的信息,此处以出错时显示脚本名称为例。而-- "$@"这里表示getopt指令不解
# 析"$@"这一堆参数
#
ARGS=`getopt -o hs:m:f:S:n:c:M:d:b:p:D: --long help,scale:,maps:,shuffles:,spark-master:,exec-num:,exec-cores:,exec-mem:,driver-mem:,benchmark:,platform:,data-size: -n 'benchmark.sh' -- "$@"`
if [ $? != 0 ] #如果上一条命令(即前面执行的ARGS=`getopt ...`这个命令的返回值为0)表示用户参数使
# 用有误,此时打印帮助信息
then
echo "$USAGE"
exit 1
fi
eval set -- "${ARGS}" #此命令会将符合getopt参数规则的参数摆在前面,其他摆在后面,并在最后面添加--
# 下面的代码是根据相应的参数做出相应的处理。需要注意的是shift 2这里,表示将参数左移2个。即处理好某一个
# 参数之后,我们就将其从参数列表中移除。为什么是2也比较好理解,因为我们的脚本形式类似于下面:
# ./my_shell.sh -s 1234 --exec-num 5 这种,当处理完-s这个参数之后,-s 1234就没有用了,所以是2
while true
do
case $1 in
-h|--help)
echo "$USAGE"
exit 0
;;
-s|--scale)
echo "scale=${2}"
shift 2
;;
-m|--maps)
echo "maps=${2}"
shift 2
;;
-f|--shuffles)
sed -i "/^hibench.default.shuffle.parallelism/c\hibench.default.shuffle.parallelism $2" ${CONF_DIR}/hibench.conf
shift 2
;;
-S|--spark-master)
sed -i "/^hibench.spark.master/c\hibench.spark.master $2" ${CONF_DIR}/spark.conf
shift 2
;;
--)
break
;;
*)
echo "$USAGE"
exit 1;;
esac
done
有了上面的参数处理代码,那我们就可以以类似于./my_shell.sh -s 123 -m 4或./my_shell.sh --scale 123 -maps 4或者./my_shell.sh -s 123 --maps 4来运行脚本,运行如下:

4 加减乘除运算
4.1 shell自带的加减乘除
#!/bin/bash
# 1. expr方式。注意:expr不能执行x^y次方运算
arg1=5
arg2=5
arg3=5
add=`expr ${arg1} + ${arg2} + ${arg3}` # 加法
sub=`expr ${arg1} - ${arg2} - ${arg3}` # 减法
mul=`expr ${arg1} \* ${arg2} + ${arg3} ` # 乘法
div=`expr ${arg1} / ${arg2} + ${arg3} ` # 除法
mod=`expr ${arg1} % ${arg2}` # 取余
echo "add=${add},sub=${sub},mul=${mul},div=${div},mod=${mod}"
# 2. $(())方式
add=$(( ${arg1} + ${arg2} + ${arg3} )) # 加法
sub=$(( ${arg1} - ${arg2} - ${arg3} )) # 减法
mul=$(( ${arg1} * ( ${arg2} + ${arg3} ) )) # 乘法
div=$(( ( ${arg1} / ( ${arg2} ) + ${arg3} ) )) # 除法
mod=$(( ${arg1} + ${arg2} )) # 取余
pow=$(( ${arg1} ** ${arg2} )) # arg1^arg2
echo "add=${add},sub=${sub},mul=${mul},div=${div},mod=${mod},pow=${pow}"
# 3. $[]方式
add=$[ ${arg1} + ${arg2} + ${arg3} ] # 加法
sub=$[ ${arg1} - ${arg2} - ${arg3} ] # 减法
mul=$[ ${arg1} * ( ${arg2} + ${arg3} ) ] # 乘法
div=$[ ( ${arg1} / ( ${arg2} ) + ${arg3} ) ] # 除法
mod=$[ ${arg1} % ${arg2} ] # 取余
pow=$[ ${arg1} ** ${arg2} ] # arg1^arg2
echo "add=${add},sub=${sub},mul=${mul},div=${div},mod=${mod},pow=${pow}"
# 4. let方式
let add1=${arg1}+${arg2}+${arg3} # 加法
add2=${arg1}
let add2+=(${arg2}+${arg3}) # 加法
let sub=${arg1}-${arg2}-${arg3} # 减法
let mul=(${arg2}+${arg3})*${arg1} # 乘法,注意let mul=${arg1}*(${arg2}+${arg3})这样写会报错
let div=(${arg1}/${arg2})+${arg3} # 除法
let mod=${arg1}%${arg2} # 取余
let pow=${arg1}**${arg2} # arg1^arg2
echo "add1=${add1},add2=${add2},sub=${sub},mul=${mul},div=${div},mod=${mod},pow=${pow}"
上述代码执行结果如下:

4.2 awk进行加减乘除
# 1. 对文件每一行最后2列进行求积
cat test.txt | awk 'NR>0{print $(NF-1),$NF}'|awk '{mul = $1*$2}; {print mul}'
# 2. 对文件每一行前3列进行求和
cat test.txt | awk 'NR>0{print $1,$2,$3}'|awk '{sum = $1+$2+$3}; {print sum}'
# 3. 对文件所有行的第2列进行求和
cat test.txt | awk '{sum += $2};END {print sum}'
# 4. 对文件所有行的所有列进行求和
cat test.txt | awk '{sum += $2+$1+$3};END {print sum}'
# 5. 对文件第2列求平均值
cat test.txt | awk '{sum += $2};END {print sum/NR}'
# 6. 对文件倒数第2列求最大值
cat test.txt | awk 'NR>0{print $(NF-1)}' | awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi}; END {print "Max=", max}'
cat test.txt | awk 'BEGIN {max = 0} {if ($(NF-1)>max) max=$(NF-1) fi}; END {print "Max=", max}'
# # 7. 对文件每一列求平均值
cat test.txt | awk -F' ' '{for(i=1; i<=NF; i++) {a[i]+=$i; if($i!="") b[i]++}}; END {for(i=1; i<=NF; i++) printf "%s%s", a[i]/b[i],(i==NF?ORS:OFS)}'
5 其他
5.1 日期
date +%Y-%m-%d~%H:%M:%S # Y/m/d/H/M/S表示年/月/日/时/分/秒
5.2 sudo执行只有切换到root账号才可以执行的命令
首先说明,sudo有些指令是无法执行的,比如清理系统的buffer/cache指令

可以使用sudo bash -c "your command"来执行只有切换到root账户才能执行的指令。
5.3 文件排序
# 1. 按照文件大小查看
ls -lSh # 其中-l表示长格式显示文件信息(包括读写权限,上次修改日期等),-S表示按照文件大小排序,-h表示将文件大小转换成易读的方式(如MB、KB、GB等)。此命令默认是降序排序,如果想要升序则需要加-r(reverse)即ls -lShr
# 2. 按照文件修改日期排序
ls -lt # -t表示按时间排序,默认也是降序

本文档汇总了在Linux环境中编写Shell脚本时常用的命令,包括文本内容替换与删除、行列选择、脚本参数处理、加减乘除运算以及一些其他实用功能,如日期、sudo执行权限受限命令和文件排序等。

178

被折叠的 条评论
为什么被折叠?



