Linux shell 脚本编程-高级篇 (四)

Linux实战教学笔记12-linux三剑客之sed命令精讲 第十二节 linux三剑客之sed命令精讲 标签(空格分隔): Linux实战教学笔记-陈思齐 ---更多资料点我查看 1,前言 我们都知道,在Linux中一切皆文件,比如配置文件,日志文件,启动文件等等。如果我们相对这些文件进行一些编辑查询等操作时,我们可能会想到一些vi,vim,cat,more等命令。但是这些命令效率不高,这就好比一块空地准备搭建房子,请了10个师傅拿着铁锹挖 阅读详情

继 Linux shell 脚本编程-高级篇 (三)

 

4. 正则表达式


在 shell 脚本中成功运用 sed 编辑器和 gawk 程序的关键在于熟练使用正则表达式。这可不是件简单的事,从大量数据中过滤出特定数据可能会(而且经常会)很复杂。


4.1 什么是正则表达式



4.1.1 定义


正则表达式是所定义的模式模板(pattern template),Linux 工具可以用它来过滤文本。Linux 工具(比如 sed 编辑器或 gawk 程序)能够在处理数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉。

正则表达式模式利用通配符来描述数据流中的一个或多个字符。Linux 中有很多场景都可以使用通配符来描述不确定的数据。例如 Linux 的 ls 命令中使用通配符列出文件和目录:

    [devalone@devalone 19]$ ls -l da*
    -rw-rw-r--. 1 devalone devalone  41 7月  11 12:09 data10.txt
    -rw-rw-r--. 1 devalone devalone  83 7月  11 12:18 data11.txt
    -rw-rw-r--. 1 devalone devalone  52 1月   7 2018 data12.txt
    -rw-rw-r--. 1 devalone devalone 184 1月   7 2018 data1.txt
    -rw-rw-r--. 1 devalone devalone  68 1月   7 2018 data2.txt
    -rw-rw-r--. 1 devalone devalone  21 1月   7 2018 data3.txt
    -rw-rw-r--. 1 devalone devalone  77 1月   7 2018 data4.txt
    -rw-rw-r--. 1 devalone devalone  45 1月   7 2018 data5.txt
    -rw-rw-r--. 1 devalone devalone  92 1月   7 2018 data6.txt
    -rw-rw-r--. 1 devalone devalone 188 7月  11 10:56 data7.txt


星号通配符允许只列出满足特定条件的文件。

da* 参数会让 ls 命令只列出名字以 da 开头的文件。文件名中 da 之后可以有任意多个字符(包括什么也没有)。ls命令会读取目录中所有文件的信息,但只显示跟通配符匹配的文件的信息。

正则表达式通配符模式的工作原理与之类似。正则表达式模式含有文本或特殊字符,为 sed 编辑器和 gawk 程序定义了一个匹配数据时采用的模板。可以在正则表达式中使用不同的特殊字符来定义特定的数据过滤模式。


4.1.2 正则表达式的类型
-----------------------------------------------------------------------------------------------------------------------------------------
使用正则表达式最大的问题在于有不止一种类型的正则表达式。Linux中的不同应用程序可能会用不同类型的正则表达式。这其中包括编程语言(Java、Perl 和 Python)、Linux 实用工具(比如 sed 编辑器、gawk 程序和 grep 工具)以及主流应用(比如 MySQL 和 PostgreSQL 数据库服务器)。

正则表达式是通过正则表达式引擎(regular expression engine)实现的。正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配。

在 Linux 中,有两种流行的正则表达式引擎:

    □ POSIX 基础正则表达式(basic regular expression,BRE)引擎
    □ POSIX 扩展正则表达式(extended regular expression,ERE)引擎

大多数 Linux 工具都至少符合 POSIX BRE 引擎规范,能够识别该规范定义的所有模式符号。遗憾的是,有些工具(比如 sed 编辑器)只符合了 BRE 引擎规范的子集。这是出于速度方面的考虑导致的,因为 sed 编辑器希望能尽可能快地处理数据流中的文本。

POSIX ERE 引擎通常出现在依赖正则表达式进行文本过滤的编程语言中。它为常见模式提供了高级模式符号和特殊符号,比如匹配数字、单词以及按字母排序
的字符。gawk 程序用 ERE 引擎来处理它的正则表达式模式。

 

4.2 定义 BRE 模式
-----------------------------------------------------------------------------------------------------------------------------------------
最基本的 BRE 模式是匹配数据流中的文本字符。


4.2.1 纯文本
-----------------------------------------------------------------------------------------------------------------------------------------
在 sed 编辑器和 gawk 程序中用标准文本字符串来过滤数据。

示例:
    [devalone@devalone 20]$ echo "This is a test" | sed -n '/test/p'
    This is a test
    [devalone@devalone 20]$ echo "This is a test" | sed -n '/trial/p'
    [devalone@devalone 20]$

    [devalone@devalone 20]$ echo "This is a test" | gawk '/test/{print $0}'
    This is a test
    [devalone@devalone 20]$ echo "This is a test" | gawk '/trial/{print $0}'
    [devalone@devalone 20]$

第一个模式定义了一个单词 test。sed 编辑器和 gawk 程序脚本用它们各自的 print 命令打印出匹配该正则表达式模式的所有行。由于 echo 语句在文本
字符串中包含了单词 test,数据流文本能够匹配所定义的正则表达式模式,因此 sed 编辑器显示了该行。

第二个模式也定义了一个单词,这次是 trial。因为 echo 语句文本字符串没包含该单词,所以正则表达式模式没有匹配,因此 sed 编辑器和 gawk 程序
都没打印该行。

正则表达式并不关心模式在数据流中的位置。它也不关心模式出现了多少次。一旦正则表达式匹配了文本字符串中任意位置上的模式,它就会将该字符串
传回 Linux 工具。

关键在于将正则表达式模式匹配到数据流文本上。重要的是记住正则表达式对匹配的模式非常挑剔。

第一条原则就是:正则表达式模式都区分大小写。这意味着它们只会匹配大小写也相符的模式。

示例:
    [devalone@devalone 20]$ echo "This is a test" | sed -n '/this/p'
    [devalone@devalone 20]$

    [devalone@devalone 20]$ echo "This is a test" | sed -n '/This/p'
    This is a test

第一次尝试没能匹配成功,因为 this 在字符串中并不都是小写,而第二次尝试在模式中使用大写字母,所以能正常工作。

在正则表达式中,不用写出整个单词。只要定义的文本出现在数据流中,正则表达式就能够匹配。

示例:
    [devalone@devalone 20]$ echo "The books are expensive" | sed -n '/book/p'
    The books are expensive

尽管数据流中的文本是 books,但数据中含有正则表达式 book,因此正则表达式模式跟数据匹配。当然,反之正则表达式就不成立了。

示例:
    [devalone@devalone 20]$ echo "The book is expensive" | sed -n '/books/p'
    [devalone@devalone 20]$

完整的正则表达式文本并未在数据流中出现,因此匹配失败,sed 编辑器不会显示任何文本。

也不用局限于在正则表达式中只用单个文本单词,可以在正则表达式中使用空格和数字。

示例:
    [devalone@devalone 20]$ echo "This is line number 1" | sed -n '/ber 1/p'
    This is line number 1

在正则表达式中,空格和其他的字符并没有什么区别。

示例:
    [devalone@devalone 20]$ echo "This is line number1" | sed -n '/ber 1/p'
    [devalone@devalone 20]$

如果在正则表达式中定义了空格,那么它必须出现在数据流中。甚至可以创建匹配多个连续空格的正则表达式模式。

示例:
    [devalone@devalone 20]$ cat data1
    This is a normal line of test.
    This is  a line with too many space
    [devalone@devalone 20]$ sed -n '/  /p' data1
    This is  a line with too many space

单词间有两个空格的行匹配正则表达式模式。这是用来查看文本文件中空格问题的好办法。


4.2.2 特殊字符
-----------------------------------------------------------------------------------------------------------------------------------------
在正则表达式模式中使用文本字符时,有些事情值得注意。在正则表达式中定义文本字符时有一些特例。有些字符在正则表达式中有特别的含义。

正则表达式识别的特殊字符包括:

    .*[]^${}\+?|()

要记住不能在文本模式中单独使用这些字符。

如果要用某个特殊字符作为文本字符,就必须转义。在转义特殊字符时,需要在它前面加一个特殊字符来告诉正则表达式引擎应该将接下来的字符当作普通的
文本字符。这个特殊字符就是反斜线(\)。

示例:    如果要查找文本中的美元符,要在它前面加个反斜线 \

    [devalone@devalone 20]$ cat data2
    The cost is $4.00
    [devalone@devalone 20]$ sed -n '/\$/p' data2
    The cost is $4.00

由于反斜线是特殊字符,如果要在正则表达式模式中使用它,必须对其转义,这样就产生了两个反斜线。

示例:
    
    [devalone@devalone 20]$ echo "\ is a special character" | sed -n '/\\/p'
    \ is a special character

尽管正斜线不是正则表达式的特殊字符,但如果它出现在 sed 编辑器或 gawk 程序的正则表达式中,会得到一个错误。

    [devalone@devalone 20]$ echo "3 / 2" | sed -n '///p'
    sed: -e expression #1, char 2: No previous regular expression

要使用正斜线,也需要进行转义。

示例:
    [devalone@devalone 20]$ echo "3 / 2" | sed -n '/\//p'
    3 / 2

现在 sed 编辑器能正确解释正则表达式模式了。

    

4.2.3 锚字符
-----------------------------------------------------------------------------------------------------------------------------------------
默认情况下,当指定一个正则表达式模式时,只要模式出现在数据流中的任何地方,它就能匹配。有两个特殊字符可以将模式锁定在数据流中的行首或行尾。


■ 锁定在行首
-----------------------------------------------------------------------------------------------------------------------------------------
脱字符(^)定义从数据流中文本行的行首开始的模式。如果模式出现在行首之外的位置,正则表达式模式则无法匹配。

要用脱字符,就必须将它放在正则表达式中指定的模式前面。

示例:
    [devalone@devalone 20]$ echo "The book store" | sed -n '/^book/p'
    [devalone@devalone 20]$
    
    [devalone@devalone 20]$ echo "Books are great" | sed -n '/^Book/p'
    Books are great

脱字符会在每个由换行符决定的新数据行的行首检查模式。

示例:

    [devalone@devalone 20]$ cat data3
    This is a test line
    this is another test line.
    A line that tests this feature.
    Yet more testing of this

    [devalone@devalone 20]$ sed -n '/^this/p' data3
    this is another test line.
    [devalone@devalone 20]$

只要模式出现在新行的行首,脱字符就能够发现它。

如果将脱字符放到模式开头之外的其他位置,那么它就跟普通字符一样,不再是特殊字符了:

    [devalone@devalone 20]$ echo "This ^ is a test" | sed -n '/s ^/p'
    This ^ is a test

由于脱字符出现在正则表达式模式的尾部,sed 编辑器会将它当作普通字符来匹配。


■ 锁定在行尾
-----------------------------------------------------------------------------------------------------------------------------------------
跟在行首查找模式相反的就是在行尾查找。特殊字符美元符($)定义了行尾锚点。将这个特殊字符放在文本模式之后来指明数据行必须以该文本模式结尾。

示例:
    [devalone@devalone 20]$ echo "This is a good book" | sed -n '/book$/p'
    This is a good book
    [devalone@devalone 20]$ echo "This book is a good" | sed -n '/book$/p'
    [devalone@devalone 20]$

使用结尾文本模式的问题在于必须要留意到底要查找什么。

示例:
    [devalone@devalone 20]$ echo "There are a lot of good books" | sed -n '/book$/p'
    [devalone@devalone 20]$

将行尾的单词 book 改成复数形式,就意味着它不再匹配正则表达式模式了,尽管 book 仍然在数据流中。要想匹配,文本模式必须是行的最后一部分。


■ 组合锚点
-----------------------------------------------------------------------------------------------------------------------------------------
在一些常见情况下,可以在同一行中将行首锚点和行尾锚点组合在一起使用。

在第一种情况中,假定要查找只含有特定文本模式的数据行。

示例:

    [devalone@devalone 20]$ cat data4
    this is a test of using both anchors
    I said this is a test
    this is a test
    I'm sure this is a test
    [devalone@devalone 20]$ sed -n '/^this is a test$/p' data4
    this is a test

sed 忽略了那些不单单包含指定的文本的行。

第二种情况乍一看可能有些怪异,但极其有用。将两个锚点直接组合在一起,之间不加任何文本,这样过滤出数据流中的空白行。

示例:
    [devalone@devalone 20]$ cat data5
    This is one test line


    This is another test line
    [devalone@devalone 20]$ sed '/^$/d' data5
    This is one test line
    This is another test line

定义的正则表达式模式会查找行首和行尾之间什么都没有的那些行。由于空白行在两个换行符之间没有文本,刚好匹配了正则表达式模式。sed 编辑器用
删除命令 d 来删除匹配该正则表达式模式的行,因此删除了文本中的所有空白行。这是从文档中删除空白行的有效方法。

 

4.2.4 句点字符 (.)
-----------------------------------------------------------------------------------------------------------------------------------------
特殊字符句点字符 (.) 用来匹配除换行符之外的任意单个字符。它必须匹配一个字符,如果在句点字符的位置没有字符,那么模式就不成立。

示例:

    [devalone@devalone 20]$ cat data6
    This is a test of line
    THe cat is sleeping
    Tha is a very nice hat
    This test is at line four
    at ten o'clock we'll go home

    [devalone@devalone 20]$ sed -n '/.at/p' data6
    THe cat is sleeping
    Tha is a very nice hat
    This test is at line four

第一行无法匹配,而第二行和第三行就可以。第四行有点复杂。注意,我们匹配了 at,但在 at 前面并没有任何字符来匹配点号字符。其实是有的!在正则
表达式中,空格也是字符,因此 at 前面的空格刚好匹配了该模式。第五行证明了这点,将 at 放在行首就不会匹配该模式了。


4.2.5 字符组 []
-----------------------------------------------------------------------------------------------------------------------------------------
句点特殊字符在匹配某个字符位置上的任意字符时很有用。但如果想要限定待匹配的具体字符呢?在正则表达式中,这称为字符组(character class)。

可以定义用来匹配文本模式中某个位置的一组字符。如果字符组中的某个字符出现在了数据流中,那它就匹配了该模式。

使用方括号 [] 来定义一个字符组。方括号中包含所有希望出现在该字符组中的字符。然后可以在模式中使用整个组,就跟使用其他通配符一样。

下面是个创建字符组的例子:
    
    [devalone@devalone 20]$ cat data6
    This is a test of line
    THe cat is sleeping
    Tha is a very nice hat
    This test is at line four
    at ten o'clock we'll go home
    
    [devalone@devalone 20]$ sed -n '/[ch]at/p' data6
    THe cat is sleeping
    Tha is a very nice hat

这里用到的数据文件和句点特殊字符例子中的一样,但得到的结果却不一样。这次我们成功滤掉了只包含单词 at 的行。匹配这个模式的单词只有 cat 和
hat。还要注意以 at 开头的行也没有匹配。字符组中必须有个字符来匹配相应的位置。

在不太确定某个字符的大小写时,字符组会非常有用。

示例:
    [devalone@devalone 20]$ echo "Yes" | sed -n '/[Yy]es/p'
    Yes
    [devalone@devalone 20]$ echo "yes" | sed -n '/[Yy]es/p'
    yes

可以在单个表达式中用多个字符组。

示例:
    [devalone@devalone 20]$ echo "Yes" | sed -n '/[Yy]es/p'
    Yes
    [devalone@devalone 20]$ echo "yes" | sed -n '/[Yy]es/p'
    yes
    [devalone@devalone 20]$ echo "yes" | sed -n '/[Yy][Ee][Ss]/p'
    yes
    [devalone@devalone 20]$ echo "Yes" | sed -n '/[Yy][Ee][Ss]/p'
    Yes
    [devalone@devalone 20]$ echo "yeS" | sed -n '/[Yy][Ee][Ss]/p'
    yeS

正则表达式使用了 3 个字符组来涵盖了3个字符位置含有大小写的情况。

字符组不必只含有字母,也可以在其中使用数字。

示例:
    [devalone@devalone 20]$ cat data7
    This line doesn't contain a number.
    This line has 1 number on it
    This line a number 2 on it
    This line has number 4 on it

    [devalone@devalone 20]$ sed -n '/[0123]/p' data7
    This line has 1 number on it
    This line a number 2 on it

这个正则表达式模式匹配了任意含有数字0、1、2或3 的行。含有其他数字以及不含有数字的行都会被忽略掉。

可以将字符组组合在一起,以检查数字是否具备正确的格式,比如电话号码和邮编。但当尝试匹配某种特定格式时,必须小心。这里有个匹配邮编出错的例子

示例:
    [devalone@devalone 20]$ cat data8
    60633
    46201
    223001
    4353
    22203
    [devalone@devalone 20]$ sed -n '
    > /[0123456789][0123456789][0123456789][0123456789][0123456789]/p
    > ' data8
    60633
    46201
    223001
    22203

它成功过滤掉了不可能是邮编的那些过短的数字,因为最后一个字符组没有字符可匹配。但它也通过了那个六位数,尽管只定义了5个字符组。

正则表达式模式可见于数据流中文本的任何位置。经常有匹配模式的字符之外的其他字符。如果要确保只匹配五位数,就必须将匹配的字符和其他字符分开,
要么用空格,要么像这个例子中这样,指明它们就在行首和行尾。

示例:
    [devalone@devalone 20]$ sed -n '
    /^[0123456789][0123456789][0123456789][0123456789][0123456789]$/p
    ' data8
    60633
    46201
    22203

字符组的一个极其常见的用法是解析拼错的单词,比如用户表单输入的数据。可以创建正则表达式来接受数据中常见的拼写错误。

示例:
    [devalone@devalone 20]$ cat data9
    I need to have some maintenence done on my car.
    I'll pay that in a seperate invoice.
    After I pay for the maintenance my car will be as good as new.

    [devalone@devalone 20]$ sed -n '
    > /maint[ea]n[ae]nce/p
    > /sep[ea]r[ea]te/p
    > ' data9
    I need to have some maintenence done on my car.
    I'll pay that in a seperate invoice.
    After I pay for the maintenance my car will be as good as new.

本例中的两个 sed 打印命令利用正则表达式字符组来帮助找到文本中拼错的单词 maintenance和 separate。同样的正则表达式模式也能匹配正确拼写的
maintenance。


4.2.6 排除型字符组 [^]
-----------------------------------------------------------------------------------------------------------------------------------------
在正则表达式模式中,也可以反转字符组的作用。可以寻找组中没有的字符,而不是去寻找组中含有的字符。只要在字符组 [] 的开头加个脱字符 [^]。

示例:
    [devalone@devalone 20]$ cat data6
    This is a test of line
    THe cat is sleeping
    Tha is a very nice hat
    This test is at line four
    at ten o'clock we'll go home

    [devalone@devalone 20]$ sed -n '/[^ch]at/p' data6
    This test is at line four

通过排除型字符组,正则表达式模式会匹配 c或h 之外的任何字符以及文本模式。由于空格字符属于这个范围,它通过了模式匹配。但即使是排除,字符组
仍然必须匹配一个字符,所以以 at 开头的行仍然未能匹配模式。


4.2.7 区间 [-]
-----------------------------------------------------------------------------------------------------------------------------------------
可能注意到了,之前演示邮编的例子的时候,必须在每个字符组中列出所有可能的数字,这实在有点麻烦。好在有一种便捷的方法可以让人免受这番劳苦。
可以用单破折线符号在字符组中表示字符区间。只需要指定区间的第一个字符、连字符以及区间的最后一个字符就行了。根据 Linux 系统采用的字符集,
正则表达式会包括此区间内的任意字符。

现在可以通过指定数字区间来简化邮编的例子:

    [devalone@devalone 20]$ sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data8
    60633
    46201
    22203

这样可是节省了不少的键盘输入,每个字符组都会匹配 0~9 的任意数字。如果字母出现在数据中的任何位置,这个模式都将不成立。

示例:
    [devalone@devalone 20]$ echo "a8392" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "1839a" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "18a32" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p'
    [devalone@devalone 20]$

    
同样的方法也适用于字母。

示例:

    [devalone@devalone 20]$ sed -n '/[c-h]at/p' data6
    THe cat is sleeping
    Tha is a very nice hat

新的模式 [c-h]at 匹配了首字母在字母 c 和字母 h 之间的单词。这种情况下,只含有单词 at 的行将无法匹配该模式。

还可以在单个字符组指定多个不连续的区间。

示例:
    [devalone@devalone 20]$ sed -n '/[a-ch-m]at/p' data6
    THe cat is sleeping
    Tha is a very nice hat

该字符组允许区间 a~c、h~m 中的字母出现在 at 文本前,但不允许出现 d~g 的字母。

示例:
    [devalone@devalone 20]$ echo "I'm getting too fat." | sed -n '/[a-ch-m]at/p'
    [devalone@devalone 20]$

该模式不匹配 fat 文本,因为它没在指定的区间。


4.2.8 特殊的字符组
-----------------------------------------------------------------------------------------------------------------------------------------
除了定义自己的字符组外,BRE 还包含了一些特殊的字符组,可用来匹配特定类型的字符。下表列出 BRE 特殊的字符组。

    BRE 特殊字符组
    +---------------+---------------------------------------------------------------------------------
    | 组            | 描 述
    +---------------+---------------------------------------------------------------------------------
    | [[:alpha:]]    | 匹配任意字母字符,不管是大写还是小写
    +---------------+---------------------------------------------------------------------------------
    | [[:alnum:]]    | 匹配任意字母数字字符0~9、A~Z或a~z
    +---------------+---------------------------------------------------------------------------------
    | [[:blank:]]    | 匹配空格或制表符
    +---------------+---------------------------------------------------------------------------------
    | [[:digit:]]    | 匹配0~9之间的数字
    +---------------+---------------------------------------------------------------------------------
    | [[:lower:]]    | 匹配小写字母字符a~z
    +---------------+---------------------------------------------------------------------------------
    | [[:print:]]    | 匹配任意可打印字符
    +---------------+---------------------------------------------------------------------------------
    | [[:punct:]]    | 匹配标点符号
    +---------------+---------------------------------------------------------------------------------
    | [[:space:]]    | 匹配任意空白字符:空格、制表符、NL、FF、VT和CR
    +---------------+---------------------------------------------------------------------------------
    | [[:upper:]]    | 匹配任意大写字母字符A~Z
    +---------------+---------------------------------------------------------------------------------


可以在正则表达式模式中将特殊字符组像普通字符组一样使用。

示例:
    [devalone@devalone 20]$ echo "abc" | sed -n '/[[:digit:]]/p'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "abc" | sed -n '/[[:alpha:]]/p'
    abc
    [devalone@devalone 20]$ echo "abc123" | sed -n '/[[:alpha:]]/p'
    abc123
    [devalone@devalone 20]$ echo "this is, a test" | sed -n '/[[:punct:]]/p'
    this is, a test
    [devalone@devalone 20]$ echo "this is a test" | sed -n '/[[:punct:]]/p'
    [devalone@devalone 20]$

使用特殊字符组可以很方便地定义区间。可以用[[:digit:]]来代替区间[0-9]。


4.2.9 星号 (*)
-----------------------------------------------------------------------------------------------------------------------------------------
在字符后面放置星号表明该字符必须在匹配模式的文本中出现 0 次或多次。

示例:
    [devalone@devalone 20]$ echo "ik" | sed -n '/ie*k/p'
    ik
    [devalone@devalone 20]$ echo "iek" | sed -n '/ie*k/p'
    iek
    [devalone@devalone 20]$ echo "ieek" | sed -n '/ie*k/p'
    ieek
    [devalone@devalone 20]$ echo "ieeek" | sed -n '/ie*k/p'
    ieeek

这个模式符号广泛用于处理有常见拼写错误或在不同语言中有拼写变化的单词。例如,如果需要写个可能用在美式或英式英语中的脚本,可以这么写:

示例:
    [devalone@devalone 20]$ echo "I'm getting a color TV" | sed -n '/colou*r/p'
    I'm getting a color TV
    [devalone@devalone 20]$ echo "I'm getting a colour TV" | sed -n '/colou*r/p'
    I'm getting a colour TV

模式中的 u* 表明字母u可能出现或不出现在匹配模式的文本中。

类似地,如果知道一个单词经常被拼错,可以用星号来允许这种错误。

示例:
    [devalone@devalone 20]$ echo "I ate a potatoe with my lunch." | sed -n '/potatoe*/p'
    I ate a potatoe with my lunch.
    [devalone@devalone 20]$ echo "I ate a potato with my lunch." | sed -n '/potatoe*/p'
    I ate a potato with my lunch.

在可能出现的额外字母后面放个星号将允许接受拼错的单词。

另一个方便的特性是将句点特殊字符和星号特殊字符组合起来。这个组合能够匹配任意数量的任意字符。它通常用在数据流中两个可能相邻或不相邻的文本
字符串之间。

示例:
    [devalone@devalone 20]$ echo "this is a regular pattern expression" | sed -n '
    > /regular.*expression/p'
    this is a regular pattern expression

可以使用这个模式轻松查找可能出现在数据流中文本行内任意位置的多个单词。

星号还能用在字符组上。它允许指定可能在文本中出现多次的字符组或字符区间。

示例:
    [devalone@devalone 20]$ echo "bt" | sed -n '/b[ae]*t/p'
    bt
    [devalone@devalone 20]$ echo "bat" | sed -n '/b[ae]*t/p'
    bat
    [devalone@devalone 20]$ echo "bet" | sed -n '/b[ae]*t/p'
    bet
    [devalone@devalone 20]$ echo "btt" | sed -n '/b[ae]*t/p'
    btt
    [devalone@devalone 20]$ echo "baat" | sed -n '/b[ae]*t/p'
    baat
    [devalone@devalone 20]$ echo "baaeeet" | sed -n '/b[ae]*t/p'
    baaeeet
    [devalone@devalone 20]$ echo "baaeeeat" | sed -n '/b[ae]*t/p'
    baaeeeat
    [devalone@devalone 20]$ echo "baakeeet" | sed -n '/b[ae]*t/p'
    [devalone@devalone 20]$

只要 a和 e字符以任何组合形式出现在b和t字符之间(就算完全不出现也行),模式就能够匹配。如果出现了字符组之外的字符,该模式匹配就会不成立。


4.3 扩展正则表达式
-----------------------------------------------------------------------------------------------------------------------------------------
POSIX ERE 模式包括了一些可供 Linux 应用和工具使用的额外符号。gawk 程序能够识别 ERE 模式,但 sed 编辑器不能。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    记住,sed 编辑器和 gawk 程序的正则表达式引擎之间是有区别的。gawk 程序可以使用大多数扩展正则表达式模式符号,并且能提供一些额外过滤功能,
    而这些功能都是 sed 编辑器所不具备的。但正因为如此,gawk 程序在处理数据流时通常才比较慢。


4.3.1 问号 (?)
-----------------------------------------------------------------------------------------------------------------------------------------
问号类似于星号,不过有点细微的不同。问号表明前面的字符可以出现 0 次或 1 次,但只限于此。它不会匹配多次出现的字符。

示例:
    [devalone@devalone 20]$ echo "bt" | gawk '/be?t/{print $0}'
    bt
    [devalone@devalone 20]$ echo "bet" | gawk '/be?t/{print $0}'
    bet
    [devalone@devalone 20]$ echo "beet" | gawk '/be?t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "beeeet" | gawk '/be?t/{print $0}'
    [devalone@devalone 20]$

如果字符 e 并未在文本中出现,或者它只在文本中出现了 1 次,那么模式会匹配。

与星号一样,可以将问号和字符组一起使用。

示例:
    [devalone@devalone 20]$ echo "bt" | gawk '/b[ae]?t/{print $0}'
    bt
    [devalone@devalone 20]$ echo "bat" | gawk '/b[ae]?t/{print $0}'
    bat
    [devalone@devalone 20]$ echo "bot" | gawk '/b[ae]?t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "bet" | gawk '/b[ae]?t/{print $0}'
    bet
    [devalone@devalone 20]$ echo "baet" | gawk '/b[ae]?t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "beat" | gawk '/b[ae]?t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "beet" | gawk '/b[ae]?t/{print $0}'
    [devalone@devalone 20]$

如果字符组中的字符出现了 0 次或 1 次,模式匹配就成立。但如果两个字符都出现了,或者其中一个字符出现了2次,模式匹配就不成立。


4.3.2 加号 (+)
-----------------------------------------------------------------------------------------------------------------------------------------
加号是类似于星号的另一个模式符号,但跟问号也有不同。加号 + 表明前面的字符可以出现 1 次或多次,但必须至少出现 1 次。如果该字符没有出现,那么
模式就不会匹配。

示例:
    [devalone@devalone 20]$ echo "beeet" | gawk '/be+t/{print $0}'
    beeet
    [devalone@devalone 20]$ echo "beet" | gawk '/be+t/{print $0}'
    beet
    [devalone@devalone 20]$ echo "bet" | gawk '/be+t/{print $0}'
    bet
    [devalone@devalone 20]$ echo "bt" | gawk '/be+t/{print $0}'
    [devalone@devalone 20]$

如果字符e没有出现,模式匹配就不成立。

加号同样适用于字符组,与星号和问号的使用方式相同。

示例:
    [devalone@devalone 20]$ echo "bt" | gawk '/b[ae]+t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "bet" | gawk '/b[ae]+t/{print $0}'
    bet
    [devalone@devalone 20]$ echo "beat" | gawk '/b[ae]+t/{print $0}'
    beat
    [devalone@devalone 20]$ echo "beet" | gawk '/b[ae]+t/{print $0}'
    beet
    [devalone@devalone 20]$ echo "beeat" | gawk '/b[ae]+t/{print $0}'
    beeat

如果字符组中定义的任一字符出现了,文本就会匹配指定的模式。


4.3.3 使用花括号 ({})
-----------------------------------------------------------------------------------------------------------------------------------------
ERE 中的花括号允许为可重复的正则表达式指定一个上限。这通常称为间隔(interval)。

可以用两种格式来指定区间:

    □ m:正则表达式准确出现 m 次。
    □ m, n:正则表达式至少出现 m 次,至多 n 次。

这个特性可以精确调整字符或字符集在模式中具体出现的次数。

    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    默认情况下,gawk 程序不会识别正则表达式间隔。必须指定 gawk 程序的--re-interval 命令行选项才能识别正则表达式间隔。

示例:
    [devalone@devalone 20]$ echo "bt" | gawk --re-interval '/be{1}t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
    bet
    [devalone@devalone 20]$ echo "beet" | gawk --re-interval '/be{1}t/{print $0}'
    [devalone@devalone 20]$

通过指定间隔为 1,限定了该字符在匹配模式的字符串中出现的次数。如果该字符出现多次,模式匹配就不成立。

很多时候,同时指定下限和上限也很方便。

示例:
    [devalone@devalone 20]$ echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "bet" | gawk --re-interval '/be{1,2}t/{print $0}'
    bet
    [devalone@devalone 20]$ echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}'
    beet
    [devalone@devalone 20]$ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}'
    [devalone@devalone 20]$

在这个例子中,字符 e 可以出现 1次或 2次,这样模式就能匹配;否则,模式无法匹配。

间隔模式匹配同样适用于字符组。

示例:
    [devalone@devalone 20]$ echo "bt" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "bat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
    bat
    [devalone@devalone 20]$ echo "bet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
    bet
    [devalone@devalone 20]$ echo "beat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
    beat
    [devalone@devalone 20]$ echo "beet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
    beet
    [devalone@devalone 20]$ echo "beeat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "baeet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "baeaet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
    [devalone@devalone 20]$

如果字母a或e在文本模式中只出现了1~2次,则正则表达式模式匹配;否则,模式匹配失败。


4.3.4 管道符号 (|)
-----------------------------------------------------------------------------------------------------------------------------------------
管道符号允许在检查数据流时,用逻辑 OR 方式指定正则表达式引擎要用的两个或多个模式。如果任何一个模式匹配了数据流文本,文本就通过测试。如果
没有模式匹配,则数据流文本匹配失败。

使用管道符号的格式如下:

    expr1|expr2|...

示例:
    [devalone@devalone 20]$ echo "The cat is asleep" | gawk '/cat|dog/{print $0}'
    The cat is asleep
    [devalone@devalone 20]$ echo "The dog is asleep" | gawk '/cat|dog/{print $0}'
    The dog is asleep
    [devalone@devalone 20]$ echo "The sheep is asleep" | gawk '/cat|dog/{print $0}'
    [devalone@devalone 20]$

这个例子会在数据流中查找正则表达式 cat 或 dog。正则表达式和管道符号之间不能有空格,否则它们也会被认为是正则表达式模式的一部分。

管道符号两侧的正则表达式可以采用任何正则表达式模式(包括字符组)来定义文本。

示例:
    [devalone@devalone 20]$ echo "He has a hat." | gawk '/[ch]at|dog/{print $0}'
    He has a hat.

这个例子会匹配数据流文本中的 cat、hat或dog。


4.3.5 表达式分组 ()
-----------------------------------------------------------------------------------------------------------------------------------------
正则表达式模式也可以用圆括号()进行分组。当将正则表达式模式分组时,该组会被视为一个标准字符。可以像对普通字符一样给该组使用特殊字符。

示例:
    [devalone@devalone 20]$ echo "Sat" | gawk '/Sat(urday)?/{print $0}'
    Sat
    [devalone@devalone 20]$ echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
    Saturday

结尾的 urday分组以及问号,使得模式能够匹配完整的 Saturday或缩写 Sat。

将分组和管道符号一起使用来创建可能的模式匹配组是很常见的做法。

示例:
    [devalone@devalone 20]$ echo "cat" | gawk '/(c|b)a(b|t)/{print $0}'
    cat
    [devalone@devalone 20]$ echo "cab" | gawk '/(c|b)a(b|t)/{print $0}'
    cab
    [devalone@devalone 20]$ echo "bat" | gawk '/(c|b)a(b|t)/{print $0}'
    bat
    [devalone@devalone 20]$ echo "bab" | gawk '/(c|b)a(b|t)/{print $0}'
    bab
    [devalone@devalone 20]$ echo "tab" | gawk '/(c|b)a(b|t)/{print $0}'
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "tac" | gawk '/(c|b)a(b|t)/{print $0}'
    [devalone@devalone 20]$

模式(c|b)a(b|t)会匹配第一组中字母的任意组合以及第二组中字母的任意组合。

 

4.4 正则表达式实战
-----------------------------------------------------------------------------------------------------------------------------------------


4.4.1 目录文件计数
-----------------------------------------------------------------------------------------------------------------------------------------
写个 shell 脚本,对 PATH 环境变量中定义的目录里的可执行文件进行计数。

首先将 PATH 变量解析成单独的目录名:

    [devalone@devalone 20]$ echo $PATH
    /usr/local/protoc/bin:/home/devalone/programs/apache-tomcat-8.5.11/bin:/usr/local/apache/maven/bin:/usr/local/apache/ant/bin
    :/usr/java/latest/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/hadoop/hadoop/hadoop/bin:/opt/hadoop/hadoop/hadoop/sbin
    :/home/devalone/.local/bin:/home/devalone/bin:/home/devalone/programs/jetty/bin
    :/home/devalone/workspaces/dearall/dearall/runtime/local/bin:/home/devalone/bin/repo

要意识到 PATH 中的每个路径由冒号分隔。要获取可在脚本中使用的目录列表,就必须用空格来替换冒号。sed 编辑器用一条简单表达式就能完成替换工作。

    [devalone@devalone 20]$ echo $PATH | sed 's/:/ /g'

分离出目录之后,就可以使用标准 for 语句中来遍历每个目录:

    mypath=$(echo $PATH | sed 's/:/ /g')
    for directory in $mypath
    do
    ...
    done

一旦获得了单个目录,就可以用 ls 命令来列出每个目录中的文件,并用另一个 for 语句来遍历每个文件,为文件计数器增值。

最终脚本如下:

    [devalone@devalone 20]$ cat countfiles.sh
    #!/bin/bash
    # count number of files in your PATH
    mypath=$(echo $PATH | sed 's/:/ /g')
    count=0
    for directory in $mypath
    do
            check=$(ls $directory)
            for item in $check
            do
                    count=$[ $count + 1 ]
            done
            echo "$directory - $count"
            count=0
    done

运行:
    [devalone@devalone 20]$ ./countfiles.sh
    /usr/local/protoc/bin - 1
    /home/devalone/programs/apache-tomcat-8.5.11/bin - 23
    /usr/local/apache/maven/bin - 6
    /usr/local/apache/ant/bin - 13
    /usr/java/latest/bin - 49
    /usr/local/bin - 4
    /usr/bin - 1909
    /usr/local/sbin - 0
    /usr/sbin - 687
    /opt/hadoop/hadoop/hadoop/bin - 11
    /opt/hadoop/hadoop/hadoop/sbin - 29
    /home/devalone/.local/bin - 0
    /home/devalone/bin - 1
    /home/devalone/programs/jetty/bin - 0
    /home/devalone/workspaces/dearall/dearall/runtime/local/bin - 2
    /home/devalone/bin/repo - 1


4.4.2 验证电话号码
-----------------------------------------------------------------------------------------------------------------------------------------
电话号码有几种常见的形式:

    (123)456-7890
    (123) 456-7890
    123-456-7890
    123.456.7890

这样用户在表单中输入的电话号码就有 4 种可能。正则表达式必须足够强大,才能处理每一种情况。

在构建正则表达式时,最好从左手边开始,然后构建用来匹配可能遇到的字符的模式。在这个例子中,电话号码中可能有也可能没有左圆括号。可以用如下
模式来匹配:
    
    ^\(?
    
脱字符用来表明数据的开始。由于左圆括号是个特殊字符,因此必须将它转义成普通字符。问号表明左圆括号可能出现,也可能不出现。

紧接着就是 3 位区号。在美国,区号以数字 2 开始(没有以数字 0或 1开始的区号),最大可到 9。要匹配区号,可以用如下模式:

    [2-9][0-9]{2}

这要求第一个字符是 2~9 的数字,后跟任意两位数字。

在区号后面,收尾的右圆括号可能存在,也可能不存在。

    \)?

在区号后,存在如下可能:有一个空格,没有空格,有一条单破折线或一个点。可以对它们使用管道符号,并用圆括号进行分组:

    (| |-|\.)

第一个管道符号紧跟在左圆括号后,用来匹配没有空格的情形。必须将句点字符转义,否则它会被解释成可匹配任意字符。

紧接着是 3 位电话交换机号码。这里没什么需要特别注意的:

    [0-9]{3}

在电话交换机号码之后,必须匹配一个空格、一条单破折线或一个点(这次不用考虑匹配没有空格的情况,因为在电话交换机号码和其余号码间必须有至少
一个空格):

    ( |-|\.)
    
最后,必须在字符串尾部匹配 4 位本地电话分机号:

    [0-9]{4}$

完整的模式如下:

    ^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}$
    
可以在 gawk 程序中用这个正则表达式模式来过滤掉不符合格式的电话号码。

创建一个简单脚本,在脚本中调用 gawk 程序来使用该正则表达式,然后用这个脚本来过滤的电话薄。

脚本如下:

    [devalone@devalone 20]$ cat isphone.sh
    #!/bin/bash
    # script to filter out bad phone numbers
    gawk --re-interval '/^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}$/{print $0}'

运行:

    [devalone@devalone 20]$ echo "317-555-1234" | ./isphone.sh
    317-555-1234
    [devalone@devalone 20]$ echo "000-555-1234" | ./isphone.sh
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "312-555-1234" | ./isphone.sh
    312-555-1234

或者将含有电话号码的整个文件重定向到脚本来过滤掉无效的号码:

    [devalone@devalone 20]$ cat phonelist
    000-000-0000
    123-456-7890
    212-555-1234
    (317)555-1234
    (202) 555-1234
    33523
    1234567890
    234.123.4567
    
    [devalone@devalone 20]$ cat phonelist | ./isphone.sh
    212-555-1234
    (317)555-1234
    (202) 555-1234
    234.123.4567

只有匹配该正则表达式模式的有效电话号码才会出现。


4.4.3 解析邮件地址
-----------------------------------------------------------------------------------------------------------------------------------------
邮件地址的基本格式为:

    username@hostname

username 值可用字母数字字符以及以下特殊字符:

    □ 点号 (.)
    □ 连字符 (-)
    □ 加号 (+)
    □ 下划线 (_)

在有效的邮件用户名中,这些字符可能以任意组合形式出现。

邮件地址的 hostname 部分由一个或多个域名和一个服务器名组成。服务器名和域名也必须遵照严格的命名规则,只允许字母数字字符以及以下特殊字符:

    □ 点号 (.)
    □ 连字符 (-)
    □ 下划线 (_)
    
服务器名和域名都用点分隔,先指定服务器名,紧接着指定子域名,最后是后面不带点号的顶级域名。

从左侧开始构建这个正则表达式模式。用户名中可以有多个有效字符:

    ^([a-zA-Z0-9_\-\.\+]+)@

这个分组指定了用户名中允许的字符,加号表明必须有至少一个字符。下一个字符很明显是 @,没什么意外的。

hostname 模式使用同样的方法来匹配服务器名和子域名:

    ([a-zA-Z0-9_\-\.]+)

这个模式可以匹配如下文本:

    server
    server.subdomain
    server.subdomain.subdomain

对于顶级域名,有一些特殊的规则。顶级域名只能是字母字符,必须不少于二个字符(国家或地区代码中使用),并且长度上不得超过五个字符。下面就是
顶级域名用的正则表达式模式:

    \.([a-zA-Z]{2,5})$

将整个模式放在一起会生成如下模式:

    ^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$

这个模式会从数据列表中过滤掉那些格式不正确的邮件地址。现在可以创建脚本来实现这个正则表达式:

    [devalone@devalone 20]$ cat isemail.sh
    #!/bin/bash
    # script to filter out bad emails
    gawk --re-interval '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/{print $0}'

运行:
    [devalone@devalone 20]$ echo "rich@here.now" | ./isemail.sh
    rich@here.now
    [devalone@devalone 20]$ echo "rich@here.now." | ./isemail.sh
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "rich@here.n" | ./isemail.sh
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "rich@here-now" | ./isemail.sh
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "deva.lone@here.now" | ./isemail.sh
    deva.lone@here.now
    [devalone@devalone 20]$ echo "deva_lone@here.now" | ./isemail.sh
    deva_lone@here.now
    [devalone@devalone 20]$ echo "deva/lone@here.now" | ./isemail.sh
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "deva#lone@here.now" | ./isemail.sh
    [devalone@devalone 20]$
    [devalone@devalone 20]$ echo "deva*lone@here.now" | ./isemail.sh
    [devalone@devalone 20]$

 

系列目录:

Linux shell 脚本编程-高级篇 (一)

Linux shell 脚本编程-高级篇 (二)

Linux shell 脚本编程-高级篇 (三)

Linux shell 脚本编程-高级篇 (四)

Linux shell 脚本编程-高级篇 (五)

Linux shell 脚本编程-高级篇 (六)

Linux shell 脚本编程-高级篇 (七)

 

 

-----------------------------------------------------------------------------------------------------------------------------------------
参考:

    《Linux 命令行与 shell 脚本编程大全》 第 3 版 —— 2016.8(美)Richard Blum  Cristine Bresnahan

Linux SHELL 脚本编程详解 Linux SHELL 脚本编程脚本编程详解名词解释shell 脚本脚本中的条件测试bash 测试分类脚本的状态返回值脚本语法检测和调试执行编程脚本之用户交互脚本执行方式1、选择执行if 语句case 语句2、循环执行1、for 循环LIST 列表的生成方式for 循环 示例:for 循环的特殊用户2、while 循环3、until 循环脚本示例 脚本编程详解 编程语言的分类:根据运行方式 1、... 阅读详情

相关推荐

Linux Shell脚本编程大全:入门到高级技巧

Linux Shell脚本是一种用于自动化常规任务的脚本语言。它允许用户通过编写一系列命令来控制Linux系统的行为。Shell脚本经常被系统管理员和开发人员用于软件部署、系统监控、任务调度等场景。理解Shell脚本的基本工作原理和结构对于任何在Linux环境下工作的IT专业人员来说,都是一个重要的技能点。变量的定义和赋值是编写脚本时的基础操作。它们为脚本提供了可操作的数据。函数是一组命令的集合,可以被重复调用执行。在Shell脚本中,函数的使用提高了代码的复用性和可维护性。

weixin_32099703的博客 748

Linux sed指令报错:sed: -e expression #1, char 4: extra characters after command

搞了半天没解决啊,网上说要加什么转义,我加了都没有用,我直接用数字写死了,,,,

Dontla的博客 4343

高级Salesforce开发面试题

自定义设置允许您创建自定义数据集,以及为组织、配置文件或特定用户创建和关联自定义数据。自定义元数据类似于自定义设置,但是自定义元数据类型中的记录被视为元数据而不是数据。自定义设置有列表和层次自定义设置两种。自定义元数据中没有此类类型。此外,自定义元数据不支持基于用户配置文件或特定用户的层次结构类型的数据。自定义设置现在不再支持关系字段。但您可以在自定义元数据对象之间创建查找。元数据查询不占用查询sql次数的限制。

weixin_45663522的博客 1246

shell 编程的老臣 - sed

vi/vim 的世界里多了两个兄弟:sed 和 gawk. sed: stream editor. 在编辑器处理数据之前,根据事先提供的规则来编辑数据流。 sed 有点类似于 Kafka, 对数据进行一行一行的编辑,行云流水,没有半点拖沓。当然 kafka 更加强大,实时捕获数据,还能指定更复杂的处理逻辑,并且能够发送到任何地方保存起来。sed 能接受的源头是文本文件,最终的结果还只能是普通的文本...

wujiandao的专栏 2216

多GPU时代的虚拟内存革命:CUDA VMM API的跨设备协同设计哲学

本文深入探讨了NVIDIA CUDA VMM API在多GPU系统中的虚拟内存管理革命,解决了传统Peer Access的显存碎片化和同步开销问题。通过地址-内存解耦、按需映射和精细权限控制,VMM API为分布式训练提供了高效的内存协同方案,显著提升大模型训练性能。

weixin_29251337的博客 535

A股量化实战:用Python回测动量因子策略(附聚宽完整代码)

本文详细介绍了如何在A股市场使用Python和聚宽平台,实战回测一个动量因子量化交易策略。从环境搭建、数据获取到完整的策略代码实现与回测分析,手把手教你验证“强者恒强”的投资逻辑,并提供参数优化与实战避坑指南,助力量化新手迈出第一步。

weixin_29264201的博客 977

sed: -e expression #1, char 8: unterminated `s‘ command

sed: -e expression #1, char 8: unterminated `s' command

有问题请直接说问题就好 1万+

2024最新超详细无痛安装PyTorch,包括下载地址、环境配置与各种避坑指南

PyTorch更新很快,2024最新下载安装经验贴,包括anaconda+CUDA+cuDNN+PyTorch四部分的下载和安装。文章详细介绍了下载地址、环境配置、虚拟环境建立的问题,还温馨提示了各种闭坑指南。有需要的友友快过来康康!

qq_43596278的博客 11万+

linux sed 命令

======博主所学知识来着于恩师马哥的亲授====== 马哥教育“2014夏令营”开始啦!!!马哥教育是目前性价比最高的Linux培训,国内好评度排名第一,并被网友称为Linux界的"黄埔军校",全部课程采用Centos6.5x86_64讲解,经过几期网络班的总结和锤炼,逐渐完善的课程体系,学员学习进度监督和优质的考试系统检验学员掌握程度,活跃的在线答疑环节,名师陪伴,牛人指点,精彩不容错

linuxarmsummary的专栏 1万+

【ESP32 S3 开发】基于I2S协议驱动INMP441数字麦克风 实现语音采集

注意INMP441的 L/R接地之后才稳定输出数据 否则一直都是0WAV格式说明这里主要是想说wav文件重要的就是生成一个wavhead来标识它是一个wave文件,wave文件的data chunk 中的data部分还是PCM编码格式的数据,直接从I2S读进去就可以,不需要压缩。wav文件的头一般由4个chunk组成。 以16bit深度为例,代码如下。其他深度可以根据注释自行计算。 I2S -> DAC i2s_read()函数,向flash中划分的一个buff当中读入byte数组。以16bit深度为例,一

m0_43395703的博客 1万+

3线SWD接线终极指南:用Jlink调试非3.3V设备的5个关键细节

本文详细解析了使用Jlink调试非3.3V设备时,3线SWD接线的5个关键细节。核心在于正确理解并连接Vref引脚以实现电压适配,避免供电冲突,并掌握精简接线法与固件修复技巧。文章以STM32F205等芯片为例,指导开发者安全、高效地进行混合电压调试。

e4f5g6h7的博客 440

【Linux】基础篇四--shell脚本编程

Linux学习4--shell脚本编程一、shell编程-变量1、shell脚本的基础知识2、shell变量二、shell编程-功能语句1、说明性语句2、常用功能性语句3、测试语句三、shell编程-分支语句1、条件语句2、多路分支语句四、shell编程-循环语句1、循环语句for的用法2、循环语句while的用法3、循环控制语句五、shell编程-函数1、shell函数调用2、函数变量作用域 一、shell编程-变量 1、shell脚本的基础知识 (1)shell脚本的本质 程序语言包括编译型语言与解释型

修成真的博客 8168

MATLAB - 使用 RRT 进行挖掘机运动规划

本例演示了如何使用运动规划器在包含障碍物的环境中为挖掘机规划路径。在此示例中,您将以运动树的简化形式为挖掘机建模,然后使用基于采样的运动规划器确定挖掘机在存在障碍物的两个姿势之间的可行路径。在 Simscape™ 多体™ 模型中模拟结果。

机器人控制与仿真应用 1852

Linux Shell 脚本编程基础知识篇—shell简介以及基本操作

Shell本身是一个用C语言编写的程序, 它是用户使用Linux的桥梁。Shell既是一种命令语言, 又是一种程序设计语言。所有的Linux命令都是Shell脚本语言。

weixin_55767624的博客 2723

基于STM32设计的电能质量控制系统_353

本项目基于STM32F103RCT6微控制器设计了一套电能质量控制系统,实现了对火焰、烟雾、环境温湿度、电压、电流及功率等多项参数的实时监测与报警。系统通过MQ2烟雾传感器、火焰传感器、SHT30温湿度传感器及电力参数采集模块采集数据,采用高电平触发有源蜂鸣器进行异常报警。采集的数据通过ESP8266无线模块以AP+TCP模式上传至基于Qt开发的手机APP和电脑上位机,实现远程实时监控和历史数据管理。系统配备1.44寸LCD显示屏,实现本地数据显示。软件采用Keil5开发,采用寄存器编程方式,提高系统响应速

255

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Linux 高级 Shell 脚本编程:掌握 Shell 脚本精髓,提升工作效率

函数体高级 Shell 脚本编程是提升 Shell 脚本编程技能的关键。通过学习函数、数组、高级控制结构和脚本调试技巧,你可以编写更高效、更灵活和更易于维护的脚本。掌握这些技能可以帮助你更好地利用 Shell 脚本解决实际问题,提高工作效率。

weixin_39372311的博客 1138

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Linux 之shell脚本编程

01 Linux 系统环境 文件系统结构 / 虚拟目录的根目录。通常不会在这里存储文件 /bin 二进制目录,存放许多用户级的GNU工具 /boot 启动目录,存放启动文件 /dev 设备目录,Linux在这里创建设备节点 /etc 系统配置文件目录 /home 主目录,Linux在这里创建用户目录 /lib 库目录,存放系统和应用程序的库文件 /media 媒体目录,可移动媒体设备的常用挂载点 /root root用户的主目录 /sbin 系统二进制目录,存放许多GNU管理员级工

wangprince2017 6219

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Linux之Shell脚本编程入门

Linux之Shell脚本编程入门,包括shell变量、运算符、条件判断、流程控制等语法案例

yuanjinshenglife的专栏 2342

linux系统篇shell脚本

Shell脚本篇

2301_81684021的博客 1266

Linux Shell 脚本编程基础知识篇—shell 运算命令详解

各位好,我是练小杰,本文继续Linux shell脚本编程的基础知识内容,接着讲算术运算命令的详细操作,主要是led命令,read命令,be命令,expr命令等。

weixin_55767624的博客 1738

Linux shell高级编程(上)

1. 概述在前面的章节中,我们讲解了shell脚本的基本编程,包括结构化命令,读取用户输入和测试命令。而这篇文章主要是描述shell脚本的高级编程部分,包括创建函数,流式编辑器sed和gawk的基本用法。2. 函数部分(1)基本格式:function name() {commands}示例:!/bin/bash #using a function in a script #格式:function name(){ command} function func(){ echo "this is an e

4870

Linux基础命令-SHELL脚本编程基础

Linux基础命令-SHELL脚本编程基础SHELL脚本编程基础一、编程基础1. 编程基础2. 程序的执行方式3. 编译和解释型语言4. 编程基本概念二、脚本基本格式1. shell脚本基础2. 创建shell脚本3. 脚本规范4. 编程基本概念5. shell脚本示例6. 脚本调试三、变量1. 变量2. bash中变量的种类a. 局部变量b. 环境变量c. 只读和位置变量3. 退出状态4. 退出...

qq_41596208的博客 1604

《Shell脚本编程实战营》Shell脚本中变量的高级特性,如数组、关联数组等的使用

在Shell脚本编程中,变量是存储和操作数据的基础。掌握变量的高级特性,能让我们编写出更高效、灵活的脚本。本文将深入探讨Shell脚本中数组和关联数组等高级变量的使用。

鸽芷咕的博客 1477

【Linux】内功篇:Shell脚本编程

在Linux系统中进行嵌入式开发,需要懂得Shell脚本的知识,以提高实际工作能力,克服嵌入式Linux学习过程中的盲点。因此,本篇记载Shell脚本编程的基础和重点知识,来源于达内---Shell完整版教程开源,但本篇基于Ubuntu系统而非Centos。若涉及版权问题,请联系删除!

致力于Linux的博客 867

linux高级系统编程之shell脚本

既是一种应用程序,也是一种程序设计语言。

m0_75253775的博客 701

Linux高级shell脚本

Linux之shell脚本编写

mitao666的博客 8840
上一篇: Linux shell 脚本编程-高级篇 (三)
下一篇: Linux shell 脚本编程-高级篇 (五)
devalone
博客等级 码龄17年 108粉丝 80原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值