shell 命令专栏总结

一、菜鸟教程

1、只读变量 readonly

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

#!/bin/bash
myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com"
/bin/sh: NAME: This variable is read only.

2、单引号与双引号的区别

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;但双引号中可以有变量

3、字符串应用

3.1 获取字符串长度

使用 ${#string}或者 ${#string[0]} 获取字符串长度;

3.2 截取子字符串

 string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

4、Shell 数组

4.1 数组定义、取值

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。用括号表示数组,用空格分隔元素,形式如下:

array_name=(value0 value1 value2 value3)
# 或者
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen

取值

valuen=${array_name[n]}

4.2 数组的 '@' 位存储所有元素

  • 取数组长度,即取 ‘@‘ 位的长度
echo ${#array_name[@]}

5、多行注释

使用 Here 文档进行多行注释,句型可以为

:<<EOF
content
EOF
# 或者 : + 空格 + 单引号
: '
content
'

6、Shell 传递参数

  • 具体传递参数:$n

    脚本内获取参数的格式为 $n,n 代表一个数字,0为执行语句,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数。

  • 传递到脚本的参数个数:$#
  • 脚本运行的当前进程ID号:$$
  • 以一个单字符串显示所有向脚本传递的参数:$*

    假设在脚本运行时写了三个参数 1、2、3,则 " * " 等价于 "1 2 3"(传递了一个参数)

  • 以字符串数组显示所有向脚本传递的参数:$@

    假设在脚本运行时写了三个参数 1、2、3,则"@" 等价于 "1" "2" "3"(传递了三个参数)。

7、关联数组(即map)

使用 declare -A 声明一个关联数组,关联数组的键是唯一的。

declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")
\# 或者
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"

7.1 获取关联数组的所有值与所有

echo "关联数组的所有值为: ${site[@]}"

8、算数运算符 expr

算数运算符使用 expr,并且运算公式被两个反引号包含。

#!/bin/bash
val=`expr 2 + 2`
echo "两数之和为 : $val"
##
val=`expr $a + $b`
echo "a + b : $val"

9、关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

  • 相同:[ $a -eq $b ]
  • 不同:[ $a -ne $b ]
  • 大于:[ $a -gt $b ]
  • 小于:[ $a -lt $b ]
  • 大于等于:[ $a -ge $b ]
  • 小于等于:[ $a -le $b ]
#!/bin/bash
if [ 表达式 ]
then
  func1
else
  func2
fi

10、布尔运算符

包括非运算、或运算、与运算。

  • 非运算:!,例如[ $a != $b ]
  • 或运算:-o,例如[ $a -lt 20 -o $b -gt 100 ]
  • 与运算:-a,例如[ $a -lt 20 -a $b -gt 100 ]

11、逻辑运算

如果使用逻辑运算符,条件控制应该使用双括号测试[[]]

### condition1
if [[ $a -lt 100 && $b -gt 100 ]]

12、双括号与单括号的区别

单括号主要用于字符串比较和文件测试,而不是算术运算。
双括号用于如下几种情况:

  • 1)算术运算和比较;
  • 2)循环和条件控制:在双括号内,你可以使用 C 风格的 for 循环(如 for ((i=0; i<n; ++i)))、初始化变量、执行递增或递减操作等。这些功能对于控制循环和条件判断非常有用,而单括号不支持这种用法。

13、文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。具体用法是 -? filename

  • -d:检测文件是否是目录;
  • -f:检测文件是否是普通文件(既不是目录,也不是设备文件);
  • -r/w/x:检测文件是否可读/写/执行;
  • -e:检测文件(包括目录)是否存在;
  • -L:检测文件是否存在并且是一个符号链接;
    实例:
if [ -r $file ]
then
   echo "文件可读"
else
   echo "文件不可读"

14、从输入流读取,显示到输出流

read 命令从标准输入中读取一行,echo 把字符串输出到标准输出。

read name 
echo "$name It is a test"

14.1 显示换行与不换行

echo 加选项 -e 表示后续字符串转义。

  • 显示换行
    echo -e "OK! \n" # -e 开启转义
    echo "It is a test"
    
  • 显示不换行
    echo -e "OK! \c" # \c 不换行
    echo "It is a test"
    # 输出结果
    OK! It is a test
    

14.2 显示命令执行结果

获取命令执行结果使用一对单反引号表示。如算数运算符 expr 公式被两个反引号包含。又如获取当前日期

echo `date`

15、printf 命令

printf 命令语法:

printf  "format-string"  [arguments...]

实例解释:%s 输出一个字符串,%ns 输出一个长度为 n 的字符串,- 表示左对齐,没有则表示右对齐。

printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234

16、条件控制语句

  • if-else 的[...]判断句中大于使用-gt,小于使用-lt
  • if-else 的((...))判断句中大于和小于直接使用 ><
    if condition1
    then 
      command1
    elif condition2
    then
      command2
    else
      commandn
    fi
    

17、for 循环

  • 格式 1:
    for var in list
    do
      command1
    done
    
  • 格式 2:
    for var in item1 item2 ... itemn
    do
      command1
    done
    

18、shell 函数

18.1 函数定义与return

  • 函数定义可用 [function] fun() ,也可用 fun()
  • return 返回值在调用该函数后通过 $? 获得;
  • return 语句只能返回一个介于 0 到 255 之间的整数,而两个输入数字的和可能超过这个范围。要解决这个问题,使用 echo 输出。
    function funWithReturn(){
        echo "这个函数会对输入的两个数字进行相加运算..."
        echo "输入第一个数字: "
        read aNum
        echo "输入第二个数字: "
        read anotherNum
        echo "两个数字分别为 $aNum 和 $anotherNum !"
        return $(($aNum+$anotherNum))
    }
    funWithReturn
    echo "输入的两个数字之和为 $? !"
    

18.2 函数参数

获取第 10 个及以上的参数,需要用 ${n} 来获取。

funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

19、输入输出重定向

  • 重定向 stderr 到 file:
    command 2> file # 覆盖
    #或者
    command 2>> file # 追加
    
  • 重定向 stdout 和 stderr 到 file:
    command > file 2>&1 # 覆盖
    #或者
    command >> file 2>&1 # 追加
    
  • 重定向 stdin 到 fileIn 同时重定向 stdout 到 fileOut:
    command < file1 > file2
    
  • 重定向到 /dev/null,屏蔽输出结果:
    command > /dev/null
    # 或者屏蔽 stderr 和 stdout
    command > /dev/null 2>&1
    

20、tail 命令

tail 不加参数默认输出最后 10 行。参数含义如下:

  • -f:循环读取。显示文件最尾部内容,并且不断刷新;
  • -n <+行数>:显示文件的尾部 n 行内容;若有 +ln 表示,从 ln 行开始至文件末尾;

21、head 命令

head 不加参数默认输出前 10 行。参数含义如下:

  • -n :显示文件的前 n 行内容
head -n 5 test.txt

20.1 实时输出文件的最新更新内容

tail -f test.txt

二、awk 详细梳理

基本操作:https://www.runoob.com/linux/linux-comm-awk.html
AWK 工作原理:https://www.runoob.com/w3cnote/awk-work-principle.html
AWK 数组:https://www.runoob.com/w3cnote/awk-arrays.html

2.1 常见的 awk 命令用法

  • 打印满足条件的行,格式:
awk '/pattern/{print NR, $0}' file

2.2 awk 命令结构

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

其中 BEGIN 的命令与 END 的命令只运行一次。例如:

awk 'BEGIN{printf "序号\t名字\t课程\t分数\n"} {print}' marks.txt

二、牛客

参考链接:https://blog.csdn.net/qq_37085158/article/details/128360865

1、正则语法

表示法 描述 示例 备注
. 匹配任何字符(除了\n之外) b.b b(中间任一字符)b
^ 匹配字符串起始部分 ^Dear 以 Dear 开头的字符串
$ | 匹配字符串终止部分 | /bin/*sh$
* 匹配 0 次或者多次前面出现的正则表达式 [A-Za-z0-9]* 字母或数字出现0次或无数次
+ 匹配 1 次或者多次前面出现的正则表达式 [a-z]+.com 字母出现一次或无数次
? 匹配 0 次或者 1 次前面出现的正则表达式 goo? 不含或只含一次"goo"
匹配N次前面出现的正则表达式 [0-9] 三位数
匹配M~N次前面出现的正则表达式 [0-9] 五位到九位的数
[...] 匹配来自字符集的任意单一字符 [aeiou] 元音字符集的任一字符
[..x-y..] 匹配 x~y 范围中的任意单一字符 [0-9], [A-Za-z] 数字或字符
^$ 表示空行

2、wc 命令

wc 命令即 "Word Count",用于统计文件的字节数、单词数、行数等信息。不使用参数,wc 一词输出行数、字符数、字节数。

参数 功能
-w 统计单词数
-c 统计字节数
-l 统计行数
-m 统计字符数
-L 显示最长行的长度

3、awk 一种处理文本文件的编程语言

awk、sed、grep 并称为 Linux 系统的文本三剑客。

参数 功能
-F 指定输入时用到的字段分隔符
-v 自定义

常用的 awk 内置变量:

awk 语法由一系列条件和动作组成,在花括号内可以有多个动作,多个动作之间用分号分隔,在多个条件和动作之间可以有若干空格,也可以没有。

  • 文件的一行称为一条记录,一列称为一个字段
内置变量名称 说明
FILENAME 当前输入文档的文件名
FNR 当前输入文档的当前行数,尤其当多个输入文档时有用
FS 设置字段分隔符,默认为空格或制表符
NF 当前行的列数,用以表示最后一个字段
NR 输入数据流的当前行号)

3.1 仅显示指定文件中第1、2列的内容

动作是 print 条件是第 1 列,第 2 列

awk '{print $1,$2}' nowcoder.txt

3.2 以冒号为间隔符,显示指定文件中第1、2列的内容

-F 指定分隔符为 :

awk -F : '{print $1,$2}' nowcoder.txt

3.3 显示系统中所有UID号码大于500的用户信息

awk -F : '$3>=500' /etc/passwd

3.4 仅显示含有指定关键字 main 的内容

awk '/main/{print}' nowcoder.txt

3.5 以冒号为分隔符,仅显示指定文件中最后一个字段的内容

awk -F : '{print $NF}' /etc/passwd

3.6 内置函数之替换字符串子串(sub 与 gsub)

  • sub(regex,sub,string):将第一次出现的子串用 regex 替换。第三个参数是可选的,默认为 $0。例如:
awk '{sub(/now/,"nowcoder"); print}' nowcoder.txt
  • gsub 是 sub() 的全局替换方式

3.7 内置函数之查找位置 index

ndex函数返回子串在字符串中的第一次出现的位置。下标从1开始算起。语法格式为:index(string, substring)

awk 'BEGIN{print index("hellow", "lo")}'

3.8 内置函数之确认长度 length

length 返回字符串的字符个数,语法格式为:length(string)

awk 'BEGIN{print length("helloworld")}'

3.9 内置函数之分割函数 split

split 函数使用有用户自定义的分割符来分割一个字符串,保存到一个数组中。如果没有提供分割符,则默认使用空格作为分割符。语法格式为:split(string, array, fieldseparator)

awk 'BEGIN{split("2013/06/16",date,"/"); print date[2],date[3]}'

4、grep 强大的文本搜索工具

grep 是全局搜索的正则表达式工具,它将搜索结果输出到屏幕。
语法格式:grep [参数] 文件...

  • 常用场景是在文件夹内搜索某字符串出现的位置,使用 grep -rnx "stringContent"
参数 功能
-i 忽略大小写
-n 列出所有的匹配行,显示行号
-w 匹配证词
-r 递归搜索
-F 匹配固定字符串的内容
-E 支持扩展的正则表达式
-l 只列出匹配的文件名,不列出具体的匹配行
-c 只输出匹配行的数量

4.1 搜索某个文件中以某个关键词开头的内容

grep ^root /etc/passwd

4.2 搜索多个文件中,包含某个关键词的内容

grep lucky /etc/passwd /etc/shadow

4.3 grep 搭配正则表达式的使用

命令格式为 grep [-cinvABC] ‘word’ filename

参数 功能
-n 表示输出符合要求的行及行号
-v 表示输出不符合要求的行及行号
4.3.1 滤出所有包含数字的行
grep '[0-9]' param.sh

如需要把行号输出,则使用 grep -n '[0-9]' param.sh

4.3.2 滤出所有不包含数字的行
grep -v '[0-9]' param.sh

5、sed 批量编辑文本文件

sed 是非交互式编辑器,它不会修改文件,除非使用 重定向保存文件或者使用 -i 选项直接修改文件内容。
默认所有行都将输出到屏幕。
sed 命令行格式为:

sed [-nefri] 'command' 输入文本
  • 常用选项
选项参数 描述
-n 仅输出经过 sed 处理的那行
-f 直接将 sed 的动作写在文件上
-i 直接修改读取的文件内容
  • 常用命令
命令参数 描述
a append 操作,追加到下一行
c 取代操作
d 后不接字符串,删除操作
i 插入操作,插入到前一行
s 取代操作,搭配正则表达式
g 行内进行全局替换
p 打印,常与 sed -n 搭配
  • 常用参数
参数 描述
-e 以指定的脚本处理输入的文本文件
-f 以指定的脚本文件处理输入的文本文件

5.1 查找某关键字

-n 选项表示只打印符合要求的行;
/main/:正则表达式,匹配包含 main 的行;
p:打印动作命令

sed -n '/main/p' test.txt

5.2 替换关键字

-i 选项表示直接替换,不打印任何信息
s 表示替换动作;g 表示全局

sed -i 's/int/INT/g' test.txt

5.3 删除文本所有含关键字的行

-i 选项表示直接在文本里删除所有含关键字 int 的行

sed -i '/int/d' test.txt

5.4 在某行前/后插入新内容

-e 选项后跟指定处理文本的脚本,-i 表示直接在文本上操作;
4a表示在第 4 行后插入新内容,改为4i则为在第 4 行前插入新内容;
\ 表示对后面空格转义,有多少个空格插入时就有多少个空格。

sed -ie '4a\    cout << "hello world" << end;' test.txt

5.4 删除多行

sed -i '2,5d' test.txt

5.5 替换多行内容

若原先内容为:

int main
{
int a = 11;
int b = 13;
int c = 15;
return 0;
}

执行命令

sed '3,5c\  cout << "gaga"' test.txt

结果为:

int main
{
cout << "gaga"
return 0;
}

6、for 循环

6.1 带 list 的 for 循环

6.1.1 实现一:依次输出 list 的内容
for item in 1 2 3 hello world
do
  echo $item
done
6.1.2 实现二:依次输出一个范围的值
for item in {1..5}
do
  echo $item
done
6.1.3 实现三:设置输出的间隔值
for item in {1..5..2}
do
  echo $item
done
6.1.4 实现四:输出当前目录下所有的文件和文件夹
for item in $(ls)
do
  echo $item
done

6.2 不带 list 的 for 循环

for item in $@
do
  echo $item
done
echo "The number of param : $#"

6.3 C 语言的 for 循环

双括号 (()) 内部可以使用C语言语法

for ((i=0;i<=10;i+=3))
do
        echo $i
done

7、tr:字符转换工具

tr 命令是批量字符转换、压缩、删除的文本工具。

tr 命令从标准输入设备读取数据,经过字符串转译后,将结果输出到标准输出设备。tr 命令需要与管道符或输入重定向操作符搭配使用。

语法格式为: tr [参数] str1 str2

参数选项 描述
-c 反选字符串1的补集(取反)
-d 删除字符串1出现的所有字符
-s 删除所有重复初夏的字符序列

8、xagrs:给其他命令传参数的过滤器

xargsextended arguments,其功能是给其他命令传参数的过滤器。

  • xargs 命令能够处理从标准输入或管道符输入的数据,并将其转换成命令参数;
  • xargs 命令可以将单行或多行输入的文本转换成其他格式;

常用参数:

参数选项 描述
-n 多行输出,常用格式 -n NumberLine
-d 指定一个定界符, 常用格式 -d(char)
-I 指定一个替换字符串 {}

8.1 以多行形式输出文件内容,每行输出 2 列内容值

cat nowcoder.txt | xargs -n 2

8.2 指定定界符为x,以多行形式输出文本内容,每行显示两段内容值

echo "FirstXSecondXThirdXFourthXFifth" | xagrs -dX -n 2

9、expr 命令计数器

expt 用于在 LINUX 系统中求表达式变量的值。常用参数:

参数选项 描述
空格 隔开每个项
\(反斜杠) 放在 shell 特定的字符前面
“”(引号) 对包含空格和其他特殊字符的字符串要用引号括起来

9.1 使用expr进行四则运算:

expr \( 10 + 10 \) \* 2 + 100

9.2 计算字串长度

expr length "sdjf"

10、sort:对文件内容进行排序

语法格式:sort [参数] 文件。不带参数选项,默认按字母排序。

常用参数 解释
-b 忽略每行前面开始的空格字符
-c 检查文件是否已经按照顺序排序
-d 除字母、数字及空格字符外,忽略其他字符
-m 将几个排序好的文件进行合并
-n 按照数值的大小排序
-o <输出文件> 将排序后的结果存入指定的文件
-t <分隔字符> 指定排序时所用的栏位分隔字符
-k 指定需要排序的栏位

10.1 按字母顺序排序

sort fruits.txt

10.2 按数字大小排序

sort num.txt

10.3 以冒号:为间隔符,对指定文件的内容按照数字大小对第3列进行排序

cat /etc/passwd | sort -t : -k 3 -n

11、Shell 中的字符串拼接

字符串拼接方式简单,直接相连即可。例如:

name='aha'
strs="hello"
new_str=${strs}" "${name}

12、字符串截取方法总结

12.1 从左边开始截取最短匹配

# 表示截取从左边开始最短匹配,删除左边字符,保留右边字符。
* 表示匹配任意数量的任意字符。#*//表示从左边开始,找到第一个//出现的位置,删除左边,保留右边

strVal=http://www.baidu.com/123.html
echo ${char#*//}
结果为:
www.baidu.com/123.html

12.2 从左边开始截取最长匹配

## 表示截取从左边开始最长匹配,删除左边字符,保留右边字符。

strVal=http://www.baidu.com/123.html
echo ${char##*/}
结果为:
123.html

12.3 从右边开始截取最短匹配

%表示截取从右边开始最短匹配,如 %/* 表示

13、获取字符串长度的3种方法

13.1 {#str}

str="edjaopjfaopsjf"
echo ${#str}

13.2 awk 的 length 方法

length($0) 统计每行的长度

## eg1:
echo $str | awk '{print length($0)}'
## eg2:
awk '{print length($0)}' /etc/passwd

13.3 wc-L 参数获取字符串长度

-L 参数对单行字符串而言,表示当前字符串的长度。对多行文件而言,表示打印最长行的长度。

echo $str | wc -L
posted @ 2024-04-29 21:29  MasterBean  阅读(87)  评论(0)    收藏  举报