bash 教程 shell 模式扩展 [MD]

博文地址

我的GitHub 我的博客 我的微信 我的邮箱
baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目录

Bash 的模式扩展

本文改编自 网道的 Bash 教程,主要为了精简大量本人不感兴趣的内容。

简介

Shell 接收到用户输入的命令以后,会根据空格将用户的输入,拆分成一个个词元(token)。然后,Shell 会扩展词元里面的特殊字符(~?*[]{}$),扩展完成后才会调用相应的命令。这种特殊字符的扩展,称为模式扩展(globbing)。

Bash 是先进行扩展,再执行命令。扩展的结果是由 Bash 负责的,与所要执行的命令无关。命令本身并不存在参数扩展,收到什么参数就原样执行。

模块扩展的英文单词是globbing,这个词来自于早期的 Unix 系统有一个/etc/glob文件,保存扩展的模板。后来 Bash 内置了这个功能,但是这个名字就保留了下来。

模式扩展与正则表达式的关系是:模式扩展的出现早于正则表达式,可以看作是原始的、早期的、低配版正则表达式,它的功能没有正则那么强大灵活,但是优点是简单和方便。

set -f  # 【set -o noglob】关闭扩展 set +f  # 【set +o noglob】打开扩展 

文件名扩展

文件名扩展字符只有 文件存在 的前提下才会扩展,如果不存在可匹配的文件名,就会原样输出。

用户主目录 ~

波浪线~会扩展成当前用户的主目录。

echo ~      # 【/home/bqt】波浪线 ~ 会扩展成当前用户的主目录 echo ~/foo  # 【/home/bqt/foo】主目录的某个子目录 echo ~root  # 【/root】用户 root 的主目录 echo ~foo   # 【~foo】如果用户名 foo 不存在,就会原样输出 echo ~+     # 扩展成当前所在的目录,等同于【pwd】命令 

单个字符 ?

字符?代表文件路径里面的任意单个字符,不包括空字符。

ls ?.txt    # 【a.txt】字符 ? 代表文件路径里面的任意单个字符,不包括空字符 ls ??.txt   # 【ab.txt】如果匹配多个字符,就需要多个 ? 连用 echo ?.bqt  # 【?.bqt】如果不存在可匹配的文件名,就会原样输出 

任意字符 *

字符*代表文件路径里面的任意数量的任意字符,包括零个字符。*不会匹配以.开头的隐藏文件

echo *.txt   # 【a.txt ab.txt】字符 * 代表文件路径里面的任意数量的任意字符,包括零个字符 echo *       # 输出当前目录所有文件,不包括以 . 开头的隐藏文件,不包括子目录中的文件 echo *.bqt   # 【*.bqt】如果不存在可匹配的文件名,就会原样输出  echo .*      # 输出当前目录所有隐藏文件(即以 . 开头的文件) echo .[!.]*  # 输出当前目录所有隐藏文件,同时排除 .(当前目录)和 ..(上级目录)这两个隐藏文件 

*只匹配当前目录,不会匹配子目录

echo */      # 输出当前目录所有子目录 echo */*     # 输出当前目录所有子目录中的所有文件 echo */*/    # 输出当前目录所有二级子目录 echo */*/*   # 输出当前目录所有二级子目录中的所有文件,有几层子目录,就必须写几层星号 

打开 globstar 参数以后,** 可以匹配零个或多个任意深度子目录(Bash 4.0 中新增)

shopt globstar    # 查询某个参数关闭还是打开,globstar 参数默认是关闭的 shopt -s globstar # 打开某个参数,打开 globstar 参数以后,** 可以匹配零个或多个子目录 shopt -u globstar # 关闭某个参数 echo **/*         # 输出当前目录以及【任意深度子目录】中的所有文件 

任一字符 []

  • 方括号扩展 [...] 可以扩展任意一个括号之中的字符
  • 排除模式 [^...][!...] 可以扩展任意一个不在方括号中的字符
  • 如果需要匹配字符 [,可以放在方括号内任意位置,不支持匹配字符 ]
  • 如果需要匹配字符 -,只能放在方括号内部的开头或结尾
echo [ab].txt  # 方括号扩展 [...] 可以扩展任意一个括号之中的字符 echo [^ab]     # 等价于 [!ab],表示扩展任意一个不在方括号中的字符 echo [[ab]     # 如果需要匹配字符 [,可以放在方括号内任意位置,不支持匹配字符 ] echo [-ab]     # 如果需要匹配字符 -,只能放在方括号内部的开头或结尾 echo [ab].bqt  # 【[ab].bqt】如果不存在可匹配的文件名,就会原样输出 

方括号扩展有一个简写形式[start-end],表示匹配一个连续的范围。

  • [a-z]:所有小写字母的字符
  • [!a-z]:所有非小写字母的字符
  • [a-zA-Z]:所有小写字母 + 大写字母
  • [a-zA-Z0-9]:所有小写字母 + 大写字母 + 数字
  • program.[co]:文件program.c与文件program.o
  • BACKUP.[0-9][0-9][0-9]:所有以BACKUP.开头,后面是三个数字的文件名

字符类 [[:class:]]

[[:class:]] 表示一个字符类,扩展成某一类特定字符之中的一个。

  • [[:digit:]]:匹配任意数字 0-9
  • [[:lower:]]:匹配任意小写字母 a-z
  • [[:upper:]]:匹配任意大写字母 A-Z
  • [[:alpha:]]:匹配任意英文字母
  • [[:alnum:]]:匹配任意英文字母与数字
  • [[:cntrl:]]:ASCII 码 0-31 的不可打印字符
  • [[:print:]]:ASCII 码 32-127 的可打印字符
  • [[:punct:]]:标点符号(除了 A-Z、a-z、0-9 的可打印字符)
  • [[:graph:]]:匹配任意英文字母、数字、标点符号
  • [[:blank:]]:空格和 Tab 键
  • [[:space:]]:空格、Tab、LF(10)、VT(11)、FF(12)、CR(13)
  • [[:xdigit:]]:匹配16进制字符(A-F、a-f、0-9)
echo [[:upper:]]*  # 输出所有以大写字母开头的文件名 echo [![:digit:]]* # 输出所有不以数字开头的文件名 echo [[:blank:]]*  # 【[[:blank:]]*】如果不存在可匹配的文件名,就会原样输出 

量词语法 ?+*!@()

量词语法用来控制模式匹配的次数。它只有在 Bash 的 extglob 参数打开的情况下才能使用,不过一般是默认打开的。

shopt extglob     # 查询某个参数关闭还是打开,extglob 参数默认是打开的 shopt -s extglob  # 打开某个参数,打开 extglob 参数以后,可以使用量词语法 shopt -u extglob  # 关闭某个参数 
  • ?(pattern-list):匹配零个或一个模式
  • *(pattern-list):匹配零个或多个模式
  • +(pattern-list):匹配一个或多个模式
  • @(pattern-list):只匹配一个模式
  • !(pattern-list):匹配给定模式以外的任何内容
ls abc?(def)       # 【abc abcdef】匹配以 abc 开头、且以零个或一个 def 结尾的文件 ls abc+(.txt|.php) # 【abc.php abc.txt】匹配以 abc 开头、且以 .txt 或 .php 结尾的文件 ls abc+(.txt)      # 【abc.txt abc.txt.txt】匹配以 abc 开头、且以 .txt 结尾的文件 ls a!(b)c.txt      # 【aac.txt ac.txt】匹配除了 abc.txt 以外,以 a 开头、且以 c.txt 结尾的文件 echo abc*(.bqt)    # 【abc*(.bqt)】如果不存在可匹配的文件名,就会原样输出 

字符串扩展

所有值 {}

大括号扩展 {...} 表示分别扩展成大括号里面的所有值。

  • 各个值之间使用逗号分隔,值可以是多字符的模式
  • 逗号前面可以没有值,表示扩展的第一项为空
  • 逗号前后不能有空格,否则,Bash 会认为这不是大括号扩展,而是独立的参数
  • 大括号可以嵌套,可以与其他模式联用,并且总是先于其他模式进行扩展
  • 大括号扩展不是文件名扩展,它总是会扩展的,这与方括号扩展 [...] 完全不同
echo {1,2,3}          # 【1 2 3】大括号扩展 {...} 表示分别扩展成大括号里面的所有值 ls {,a,abc}.txt       # 依次访问 .txt a.txt abc.txt 三个文件,而不管文件是否存在 echo a{a{1,2},b{3,4}} # 【aa1 aa2 ab3 ab4】支持嵌套 echo /bin/{cat,ba*}   # 大括号也可以与其他模式联用,并且总是先于其他模式进行扩展 

大括号扩展可直接用于for循环。

for i in {1,2,4,白乾涛} do   echo $i done 
  • 大括号扩展的简写形式 {start..end} 表示扩展成一个连续序列
  • 大括号扩展另一个简写形式 start..end..step 可指定扩展的步长
  • 简写形式支持逆序、支持嵌套
echo {01..5}          # 【01 02 03 04 05】扩展成一个连续序列 echo {0..8..2}        # 【0 2 4 6 8】可指定扩展的步长 echo {a..c}{1,2}      # 【a1 a2 b1 b2 c1 c2】多个简写形式连用,会有循环处理的效果 echo .{mp{5..3},mkv}  # 【.mp5 .mp4 .mp3 .mkv】支持逆序,支持嵌套 echo {a1..3c}         # 【{a1..3c}】遇到无法理解的简写时会原样输出,不会扩展 

美元符号扩展

变量扩展 $

Bash 将美元符号$开头的词元视为变量,将其扩展成变量值。${!string*}${!string@}返回所有匹配给定字符串string的变量名。

echo $SHELL   # 【/bin/bash】 echo ${SHELL} # 【/bin/bash】变量名也可以放在 ${} 里面 echo ${!S*}   # 返回所有以 S 开头的变量名,如果不存在,则返回空 

子命令扩展 $(...)

$(...) 可以扩展成另一个命令的运行结果,该命令的所有输出都会作为返回值。

echo $(date)       # 返回 date 命令的运行结果,注意 date 是一个命令而非一个变量 echo `date`        # 将子命令放在反引号之中,也可以扩展成命令的运行结果 echo $(ls $(pwd))  # 子命令扩展可以嵌套 

算术扩展 $((...))

$((...)) 可以扩展成整数运算的结果。

echo $((2 + 2))  # 4 

模式扩展相关的 shopt 命令

shopt命令可以调整 Bash 的行为。它有好几个参数跟通配符扩展有关。

shopt [optionname]    # 查询某个参数关闭还是打开 shopt -s [optionname] # 打开某个参数 shopt -u [optionname] # 关闭某个参数 
  • dotglob:默认关闭,可以让扩展结果包括隐藏文件,即以点开头的文件。
  • nullglob:默认关闭,可以让通配符不匹配任何文件名时,返回空字符串而非原样返回
  • failglob:默认关闭,可以让通配符不匹配任何文件名时,直接报错,而非继续让各个命令去处理。
  • extglob:默认打开,可以让 Bash 支持 ksh 的一些扩展语法。它的主要应用是支持量词语法
  • nocaseglob:默认关闭,可以让通配符扩展不区分大小写。
  • globstar:默认关闭,可以让 ** 匹配零个或多个子目录(Bash 4.0 中新增)。

模式扩展使用注意点

  • 通配符是先解释,再执行:Bash 接收到命令以后,如果发现里面有通配符,会先进行通配符扩展,然后再执行命令。
  • 文件名扩展在没有可匹配的文件时,会原样输出。
  • 所有文件名扩展只匹配单层路径,无法匹配子目录里面的文件(即:不能匹配路径分隔符/)。
  • Bash 允许文件名使用通配符,即文件名包括特殊字符。这时引用文件名,需要把文件名放在单引号或双引号里面。

2022-1-2

推荐这些文章:

bash 教程-5 shell 脚本基础 [MD]

博文地址

我的GitHub
我的博客
我的微信
我的邮箱

baiqiantao
baiqiantao
bqt20094
baiqiantao@sina.com

目录
目录目录Bash 教程脚本基础Shebang 行:#! env权限和路径:chmod PATH脚本参数:$n $# $@读取命令执行结果:$?配置项参数终止符:--脚本基础命令移除脚本参数:shift解析脚本参数:getopts终止当前脚本:exit加载外部脚本:source指定命令别名:alias脚本调试使用 -x 参数打印命令一些调试用的环境变量read 命令读取键盘输入内容逐行读取文件内容常用参数字段...

shell——函数

1. 函数返回值
#!/bin/bash

function func1()
{
echo "I will return 0"
}

function func2()
{
echo "I will return 1"
# 默认返回最近命令的 返回值
find ./ -name &>/dev/null
}

func1
echo "Last function return $?"

func2
echo "Last function return $?"

2. 函数库
# 避免库被直接调用
#!/bin/ech...

bash 教程-3 shell 变量 数组 算术表达式 函数 [MD]

博文地址

我的GitHub
我的博客
我的微信
我的邮箱

baiqiantao
baiqiantao
bqt20094
baiqiantao@sina.com

目录
目录目录Bash 教程变量 $环境变量 $PATH定义变量读取变量删除变量 unset特殊变量 $0 $# $*变量未定义的默认值 ${}声明输出变量 export声明只读变量 readonly声明时执行算术式 let声明特殊变量 declare数组 () []创建数组读取数组 ${a[i]}删除数组 unset获取数组长度 ${#a[@]}提取数组序号 ${!a[@]}提取数组成员 ${a[@]:p}追加...

bash 教程-1 shell 基础 快捷键 目录堆栈 操作历史 [MD]

博文地址

我的GitHub
我的博客
我的微信
我的邮箱

baiqiantao
baiqiantao
bqt20094
baiqiantao@sina.com

目录
目录目录Bash 教程Bash 简介Bash 基础命令Bash 基本语法命令格式注释echo 命令type 命令Bash 快捷键基础操作快捷键自定义快捷键行操作移动光标修改内容Tab 自动补全其他快捷键Bash 目录堆栈pushd popd 命令pushd popd 参数dirs 命令Bash 命令操作历史基本用法!string 语法history 命令相关快捷键感叹号快捷键Bash 命令提示符
Bash ...

shell for in 用法总结

1、遍历按空格分隔的字符串:

#!/bin/bash
s="111 222 333"
for server in $s
do
echo$s
done

2、遍历字符串列表、用空格分隔:

#!/bin/bash
for mm in a b c
do
echo$mm
done

3、遍历参数列表:

#!/bin/bash
for arg in $*
do
echo$arg
done

4、遍历文件目录:
注:$i是整个目录和文件;

#!/bin/bash
for i in ~/*.sh
do
echo$i
cat$i
done

注:for in语句也可以与` `和$( ...

bash 教程-4 shell 脚本 调试 环境 [MD]

博文地址

我的GitHub
我的博客
我的微信
我的邮箱

baiqiantao
baiqiantao
bqt20094
baiqiantao@sina.com

目录
目录目录Bash 教程脚本基础如何运行一个脚本Shebang 行:#! env权限和路径:chmod PATH脚本参数:$n $# $@读取命令执行结果:$?配置项参数终止符:--脚本基础命令移除脚本参数:shift解析脚本参数:getopts终止当前脚本:exit加载外部脚本:source指定命令别名:alias创建临时文件:mktemp响应系统信号:trap脚本调试命令错误处理几个调试参数调试参数 -x...

常用shell脚本

1.统计文件行数
#!/bin/bash
##方法一
wc -l ./code.txt | awk '{print $1}'

##方法二
awk '{print NR}' ./code.txt | tail -n 1

##方法三
awk 'ENG{print NR}' ./code.txt

##方法四
grep -c "" ./code.txt
##或者
grep -n "" ./code.txt | awk -F ":" "{print $1}"

##方法五
sed -n '$=' ./code.txt

2.打印文件的最后5行
#!/bin/bash
tail -n 5 ./co...

python shell

#!/bin/bash

cd ~/project/ParkLot/tensorrt_demos
echo "检测开始请稍等"

python3 trt_yolo.py --image cardata/camera8rainy/2016-01-08_1314.jpg --model yolov4-416

echo "检测结束"

  

...

shell的变量数组

#! /usr/bin/bash

#变量数组

function var_list
{
list=(var1 var2 var3)
for item in ${list[@]}
do
#给数组内的每个变量赋值 var ,declare -g 是申请全局变量
declare -g ${item}=$(echo "var")
done
}
var_list

echo ${var1}
echo ${var2}
echo ${var3}#结果是:
bash var_list.sh varvarvar

 

...

shell脚本接收参数

1、接收固定参数
#!/bin/bash
echo "name of this file is `basename $0` --as the same time called as $0"
echo "first param is : $1"
echo "second param is : $2"

运行结果:
空参执行
然后带两个参数执行

听不懂你在说什么

...

文章标题:bash 教程 shell 模式扩展 [MD]
文章链接:https://www.dianjilingqu.com/2856.html
本文章来源于网络,版权归原作者所有,如果本站文章侵犯了您的权益,请联系我们删除,联系邮箱:saisai#email.cn,感谢支持理解。
THE END
< <上一篇
下一篇>>