曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6405|回复: 4
打印 上一主题 下一主题

[概念] 正则表达式(beginning linux programming 4)

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2009-1-30 22:54:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、使用 \ 符号,使字符还原为其本来“面目”。如要寻找 $ ($符号在脚本应用中是特殊符号),那么就使用 \$



2、匹配模式表

[:alnum:]  Alphanumeric characters (包括文字和数字等字符)
         
[:alpha:]  Letters (字母)
         
[:ascii:]   ASCII characters (ASCII 字符)
          
[:blank:]  Space or tab (空格或者 tab 键)
          
[:cntrl:]   ASCII control characters (ASCII 控制字符)
          
[:digit:]   Digits (数字)
          
[:graph:]  Noncontrol, nonspace characters (非控制,非空格字符)
          
[:lower:]  Lowercase letters (小写字母)
          
[:print:]   Printable characters (可打印字符)
          
[:punct:]  Punctuation characters (标点字符)
          
[:space:]  Whitespace characters, including vertical tab (空白符,包含垂直 tab)
  
[:upper:]  Uppercase letters (大写字母)
          
[:xdigit:]  Hexadecimal digits (十六进制数字)

示例一
$ grep a[[:blank:]] words2.txt      #匹配字母a后面有着空格的行
Is this a dagger which I see before me,
A dagger of the mind, a false creation,
Moves like a ghost. Thou sure and firm-set earth,
$

示例二
$ grep Th.[[:space:]] words2.txt    #匹配 Th ,然后再匹配一个任意字符(.),接着匹配空格
The handle toward my hand? Come, let me clutch thee.
The curtain’d sleep; witchcraft celebrates
Thy very stones prate of my whereabout,
$

示例三
$ grep -E [a-z]\{10\} words2.txt   #匹配连续有 10 个小写字母的行
proceeding from the heat-oppressed brain?
And such an instrument I was to use.
The curtain’d sleep; witchcraft celebrates
Thy very stones prate of my whereabout,
$

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
沙发
 楼主| 发表于 2009-2-1 18:34:01 | 只看该作者

here documents

 一个从 shell 脚本传递“输入”到命令的方法是: here document

 这个“document”允许命令执行像从键盘或者从一个文件中读取,然而事实上,这些输入是来自脚本!

 一个 “here document”以 << 作为引导符号开始,后面跟着一个字符串,这个字符串在这个“document”的末尾处还需要重复写一次。用来标志 “here document”结束。

<< 是 shell 的一个重定向标签,在此它强制命令输入作为“here document”(here document,本处文档,就是把命令的输入当作是普通文本来看待)。



示例代码
#!/bin/sh

cat << !FUNKY!
hello
this is a here
document
!FUNKY!

输出结果
[beyes@localhost here_document_dir]$ sh here_document.sh
hello
this is a here
document

这种应用,使你可以调用一个交互式程序,如给一个编辑器送入一些预定义的输入。然而,更通常的应用正如上民的脚本所示---从一个脚本内部输出大量的文本。这样,就避免了在每行使用 echo 声明。另外,可以在区别符(如上面的 FUNKY)的两边使用感叹号 ! ,以减少困惑。

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
板凳
 楼主| 发表于 2009-1-31 00:04:00 | 只看该作者

参数扩展

看一个循环错在哪里
#!/bin/sh
for i in 1 2
do
echo  $i_tmp
done

输出空白。这是因为,脚本认为 i_tmp 是个空变量。但我们的本意是,用1,2来取代 $i_tmp 中的 $i !所以,在这里,我们需要对 $i 进行保护,保护方法是: ${i}_tmp

完整脚本修改后并执行
[beyes@localhost shell]$ sh parameters_expansion.sh
1_tmp
2_tmp



常用参数扩展:

${param:-default}  If param is null, then set it to the value of default.
                 (加入 param 为空,然后设其值为 default)
         
${#param}        Gives the length of param
                 (得到 param 的长度)

             
${param%word}  From the end, removes the smallest part of param that matches word and returns the rest
               (从末端起,移除掉 param 中匹配 word 的最小部分并返回其它剩下的内容)

              
${param%%word} From the end, removes the longest part of param that matches word and returns the rest
                (从末端起,移出掉 param 中匹配 word 的最长部分并返回其它剩下的内容)
              
                
${param#word}  From the beginning, removes the smallest part of param that matches word and returns the rest
               (从前端起,移除掉 param 中匹配 word 的最小部分并返回其它剩下的内容)
             
${param##word}  From the beginning, removes the longest part of param that matches word and returns the rest
               (从前端起,移除掉 param 中匹配 word 的最长部分并返回其它剩下的内容)
         

举例
#!/bin/sh

unset foo
echo ${foo:-bar}

foo=fud
echo ${foo:-bar}

foo=/usr/bin/X11/startx
echo ${foo#*/}
echo ${foo##*/}

bar=/usr/local/etc/local/networks
echo ${bar%local*}
echo ${bar%%local*}

exit 0

执行结果
[beyes@localhost shell]$ sh parameter_process.sh
bar
fud
usr/bin/X11/startx
startx
/usr/local/etc/
/usr/

结果分析:

unset foo 后,foo 变量不带任何值,所以 echo ${foo:-bar} 输出默认值 bar !

--------------------
foo=fud           
echo ${foo:-bar

--------------------
foo 被赋值 fud ,故直接输出 fud .

--------------------
foo=/usr/bin/X11/startx
echo ${foo#*/}      #从前端开始,删除掉最短匹配
echo ${foo##*/}     #从前端开始,删除掉最长匹配
--------------------
从注释中看见,第一个,最短匹配从第一个 / 就开始,所以删除掉 / 后输出;第二个,因为要删除掉最长匹配,最长的匹配发生在最后一个 / 符号处,即在 startx 前面的 / 符号。



如下形式:

${foo:?bar}   //如果 foo 不存在或者为null,则打印出 foo:bar

${foo:+bar}  //如果 foo 存在并且不为null,则打印出 bar


 
例2

转换一个 gif 文件为 jpg 文件:
cjpeg image.gif > image.jpg

若有很多个 gif 文件要转换成 jpg 文件,则可以:
#!/bin/sh

for image in *.gif
do
cjpeg $image > ${image%%gif}jpg  
done

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
地板
 楼主| 发表于 2009-1-30 23:47:36 | 只看该作者

算术扩展

可以使用 expr 命令进行简单的算术命令处理,但执行速度比较慢,因为每次处理 expr 指令时都需要调用到一个新 shell 。

一个更好的解决办法是使用: 

$((...))

示例脚本
#!/bin/sh

x=0
while [ "$x" -ne 10 ]; do
echo $x
        x=$(($x+1))
done

exit 0

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
5#
 楼主| 发表于 2009-1-30 23:37:22 | 只看该作者

命令的执行

 在写脚本时,经常需要用到命令执行的结果。也就是说,经常想要执行一个命令并且把其输出放入到一个变量中。可以这么做:

 $(command)

 一个较老的表达形式是: `command` (在通常的应用中仍然在使用)

使用 `` 来执行命令常常需要用 \\ 符号来转义字符,故容易使人迷惑。所以,所有新脚本都应该使用 $(...) 这样的形式!
 
简单比较:
#!/bin/sh
echo The current directory is $PWD  #PWD 是环境变量
echo The current users are $(who)  #执行了 who 命令
exit 0

把命令的执行结果存入变量:

whoisthere=$(who)
echo $whoisthere
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-14 19:32 , Processed in 0.078261 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表