概述

#!/bin/bash
# 告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

:<<!
多行注释...
多行注释...
多行注释...
!

字符串

echo "hi, jiler."
echo "hi, wujunpeng"

# 变量名和等号之间不能有空格
myName="wujunpeng"
echo $myName
echo ${myName}

# 只读变量
readonly myName

# 删除变量(不能删除只读变量)
unset myName

# 字符串长度,效果一样
str="test str"
echo $#str ${#str}

# 截取字符串,从第2位开始,截取1个字符
echo ${str:1:1}

获取参数

# 比如命令行执行为文件 ./start.sh
./start.sh wujunpeng firstPlan
# 在./start.sh内部获取参数时,
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
# $10 不能获取第十个参数,获取第十个参数需要${10}
$# # 表示参数个数

数组

int_arr=(1 2 3 4 5)
str_arr[0]=My # #!/usr/bin/env zsh 数组下标从1开始
str_arr[1]=name
str_arr[2]=is
str_arr[3]=wujunpeng

echo $int_arr[1]

echo "数组的元素为: ${int_arr[*]}"
echo "数组的元素为: ${int_arr[@]}"
length=${#int_arr[*]} 获取数组长度
length=${#int_arr[@]} 获取数组长度

置换

# 变量置换
word=replace
echo ${param}
echo ${param:-${word}} # 如果param为空 或 未赋值,用word的内容取代param,但param不变
echo ${param:=word} # 如果param为空 或 未赋值,用word赋值给param
echo ${param:+word} # 如果param有值,用word取代param,但param不变
# 命令置换
DATE=`date`
echo ${DATE}
# 算式置换
echo $((1+2))

if条件

a=10
b=20
if [ $a == $b ]
then
   echo "a 等于 b"
fi
if [ $a != $b ]
then
   echo "a 不等于 b"
fi
# 写成一行
if [ $a == $b ]; then echo "a 等于 b"; fi

# if后的可以使用其他的语法,判断数据是否相等
if [ $a -eq $b ] # 判断相等equals
if [ $a -ne $b ] # 判断不相等 not equals
if [ $a -gt $b ] # 判断> greater than
if [ $a -lt $b ] # 判断< less than
if [ $a -ge $b ] # 判断>= greater or equals
if [ $a -le $b ] # 判断<= less or equals
# 与或非 -a -o !,直接用&& 和 || 也支持
[ $a -lt 20 -a $b -gt 100 ] # if (a < 20 && b > 100)
[ $a -lt 20 -o $b -gt 100 ] # if (a < 20 || b > 100)

# 可以判断字符串是否为空
if [ -z $str ] # 检查字符串长度是否为0,如果为0则返回true
if [ -n $str ] # 检查字符串长度是否不为0,如果不为0则返回true
if [ $str ] # 字符串为空返回true

# 可以判断文件类型
if [ -f $fileAddress ] # 如果是普通文件(不是目录,不是设备文件)返回true
if [ -r $fileAddress ] # 检查文件是否可读;如果检查可写用-w,可执行用-x
if [ -e $fileAddress ] # 检查文件是否存在,存在返回true

test

if test -e $str # 如果文件存在

循环

for

for each in 1 2 3 4 5
do
	echo $each
done
# for循环遍历数组
int_arr=(1 2 3 4 5)
for each in ${int_arr[@]}
do
	echo $each
done
# for循环遍历带空格的元素
name_arr[0]=jiler
name_arr[1]="jiler hell"
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for each in ${name_arr[@]}
do
	echo ${each}
done
IFS=$SAVEIFS

until

a=0
until [ ! $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done

case switch

case $aNum in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    3)  echo '你选择了 3'
    ;;
    4)  echo '你选择了 4'
    ;;
    *)  echo '你没有输入 1 到 4 之间的数字'
    ;;
esac

seq序列遍历

基本语法:
1 seq [选项]… 尾数
2 seq [选项]… 首数 尾数
3 seq [选项]… 首数 增量 尾数

seq -s '#' 5 # 指定分隔符,横向输出 1#2#3#4#5
seq -s ' ' 10 # 空格作为分隔符
seq -w 1 10 # 前面补0,输出1-10
seq 1 2 10 # 从1开始,增量为2,不超过10
seq -f "%03g" 98 101 # 宽度为3,不足补0

重定向

# 输出 重定向 到test.sh文件
echo "wujunpeng" > test.sh

# 输入 重定向 到test.sh文件
command < test.sh
# 重定向输出,追加
echo "wujunpeng" >> test.sh
# 重定向输入
file < test.sh
# 将标准输出和标准错误输出 以追加的方式 重定向 到文件file
command >> file 2>&1

文件包含

# 类似于include import等,可通过两种方式
source ./test1.sh
. ./test1.sh

awk 命令 行处理

处理文本文件的语言,是一个强大的文本分析工具

awk '{print $1,$4}' log.txt # 打印出 log.txt文件 每行按空格分隔的第一个和第四个元素
awk -F, '{print $1,$2}'   log.txt # 打印出 log.txt文件 每行按逗号分隔的第一个和第四个元素
awk -F '[ ,]' '{print $1,$2,$5}' log.txt # 打印出 log.txt文件 每行按先按空格,再按逗号分隔的第一个和第四个元素
awk -va=1 '{print $1,$1+a}' log.txt # 设置变量a=1,如果$1是数字,则是加法;如果$1是字符串,则连接
awk '$2 ~ /th/ {print $2,$4}' log.txt # 第二列包含th的行,打印出第二例和第四列,~表示正则匹配
awk '/re/ ' log.txt # 输出包含re的行
awk '$2 !~ /th/ ' log.txt # 输出第二列不包含th的行
awk '!/re/ ' log.txt # 输出不包含re的行

awk -f cal.awk score.txt # cal.awk内容详见附录

sed 命令

用脚本来处理文本文件,用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。具体就不写例子了,目前其应用场景未知。

简单应用

# bc 命令
echo 'scale=2; (2.777 - 1.4744)/1' | bc # 保留两位小数进行计算
echo "obase=2;8" | bc # 十进制转二进制
echo "ibase=2;111" | bc # 二进制转十进制
echo "obase=10;ibase=2;1101" | bc # 二进制转十进制
echo "sqrt(100)" | bc # 开平方

# nohup 命令 后台运行,比如java的发布就可以用
nohup java -jar *.jar

# wc 命令
wc -l Hello.java # 统计文件中的行数 -w表示字数 -c表示字节数

# scp 命令
scp /user/wujunpeng/web/test.java wujunpeng@192.168.0.23:~/Desktop
# 如果是复制目录则用-r (-C 表示允许压缩 -P 4588表示指定端口)
scp -r /user/wujunpeng/web/test wujunpeng@192.168.0.23:~/Desktop


# xargs 命令 给命令传递参数的过滤器,也是组合多个命令的工具
seq -f "dir%03g" 1 3 | xargs mkdir # 联系创建多个目录

# curl http命令行工具
curl -o /dev/null -s -w %{http_code} https://www.baidu.com # 获取访问百度的返回值

# ps 命令
ps -ef | grep java

# 用mac电脑给手机充电的时候,有时候会出现频繁断开又链接的情况,用下面这个命令可以解决这个问题
sudo killall -STOP -c usbd

# nslookup 查询机器对应的域名
nslookup 10.3.43.4

# 端口被占用
lsof -i :8080


附录

awk文件内容

#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0

    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}