Linux操作系统实用技术总结(bash、vim、GNU make、正则表达式)

一、Bash脚本编程

参考资料:

http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/index.html

http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/index.html

http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/index.html

 

"$0" 将扩展成从命令行调用的脚本名称,"$#" 将扩展成传递给脚本的自变量数目。试验以上脚本,通过传递不同类型的命令行自变量来了解其工作原理。

有时需要一次引用 所有 命令行自变量。针对这种用途,bash 实现了变量 "$@",它扩展成所有用空格分开的命令行参数。在本文稍后的 "for" 循环部分中,您将看到使用该变量的例子。


下表列出最常用的 bash 比较运算符。同时还有如何正确使用每一选项的示例。示例要跟在 "if" 之后。例如:

 if [ -z "$myvar" ]
then
    echo "myvar is not defined"
fi
 


运算符  描述  示例 
文件比较运算符 
-e filename  如果 filename存在,则为真  [ -e /var/log/syslog ]
-d filename  如果 filename为目录,则为真  [ -d /tmp/mydir ]
-f filename  如果 filename为常规文件,则为真  [ -f /usr/bin/grep ]
-L filename  如果 filename为符号链接,则为真  [ -L /usr/bin/grep ]
-r filename  如果 filename可读,则为真  [ -r /var/log/syslog ]
-w filename  如果 filename可写,则为真  [ -w /var/mytmp.txt ]
-x filename  如果 filename可执行,则为真  [ -L /usr/bin/grep ]
filename1-nt filename2  如果 filename1比 filename2新,则为真  [ /tmp/install/etc/services -nt /etc/services ]
filename1-ot filename2  如果 filename1比 filename2旧,则为真  [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法) 
-z string  如果 string长度为零,则为真  [ -z "$myvar" ]
-n string  如果 string长度非零,则为真  [ -n "$myvar" ]
string1= string2  如果 string1与 string2相同,则为真  [ "$myvar" = "one two three" ]
string1!= string2  如果 string1与 string2不同,则为真  [ "$myvar" != "one two three" ]
算术比较运算符 
num1-eq num2  等于 [ 3 -eq $mynum ]
num1-ne num2  不等于 [ 3 -ne $mynum ]
num1-lt num2  小于 [ 3 -lt $mynum ]
num1-le num2  小于或等于 [ 3 -le $mynum ]
num1-gt num2  大于 [ 3 -gt $mynum ]
num1-ge num2  大于或等于 [ 3 -ge $mynum ]


有时,有几种不同方法来进行特定比较。例如,以下两个代码段的功能相同:

 if [ "$myvar" -eq 3 ]
then
     echo "myvar equals 3"
fi
 
 
 if [ "$myvar" = "3" ]
then
     echo "myvar equals 3"
fi
 


上面两个比较执行相同的功能,但是第一个使用算术比较运算符,而第二个使用字符串比较运算符。

循环结构:"for"

好了,已经讲了条件语句,下面该探索 bash 循环结构了。我们将从标准的 "for" 循环开始。这里有一个简单的例子:

 
 #!/usr/bin/env bash
 
 for x in one two three four
 do
     echo number $x
 done
 
 
        输出:
 
 number one
 number two
 number three
 number four
      


发生了什么?"for" 循环中的 "for x" 部分定义了一个名为 "$x" 的新环境变量(也称为循环控制变量),它的值被依次设置为 "one"、"two"、"three" 和 "four"。每一次赋值之后,执行一次循环体("do" 和 "done" 之间的代码)。在循环体内,象其它环境变量一样,使用标准的变量扩展语法来引用循环控制变量 "$x"。还要注意,"for" 循环总是接收 "in" 语句之后的某种类型的字列表。在本例中,指定了四个英语单词,但是字列表也可以引用磁盘上的文件,甚至文件通配符。看看下面的例子,该例演示如何使用标准 shell 通配符:

 #!/usr/bin/env bash
 
 for myfile in /etc/r*
 do
     if [ -d "$myfile" ]
then
       echo "$myfile (dir)"
else
       echo "$myfile"
fi
 done
 
 
        输出:
 
 /etc/rc.d (dir)
 /etc/resolv.conf
 /etc/resolv.conf~
 /etc/rpc                 
      


以上代码列出在 /etc 中每个以 "r" 开头的文件。要做到这点,bash 在执行循环之前首先取得通配符 /etc/r*,然后扩展它,用字符串 /etc/rc.d /etc/resolv.conf /etc/resolv.conf~ /etc/rpc 替换。一旦进入循环,根据 myfile 是否为目录,"-d" 条件运算符用来执行两个不同操作。如果是目录,则将 "(dir)" 附加到输出行。

还可以在字列表中使用多个通配符、甚至是环境变量:

 
 for x in /etc/r--? /var/lo* /home/drobbins/mystuff/* /tmp/${MYPATH}/*
 do
     cp $x /mnt/mydir
 done
 


Bash 将在所有正确位置上执行通配符和环境变量扩展,并可能创建一个非常长的字列表。

虽然所有通配符扩展示例使用了 绝对路径,但也可以使用相对路径,如下所示:

 
 for x in ../* mystuff/*
 do
     echo $x is a silly file
 done
 


在上例中,bash 相对于当前工作目录执行通配符扩展,就象在命令行中使用相对路径一样。研究一下通配符扩展。您将注意到,如果在通配符中使用绝对路径,bash 将通配符扩展成一个绝对路径列表。否则,bash 将在后面的字列表中使用相对路径。如果只引用当前工作目录中的文件(例如,如果输入 "for x in *"),则产生的文件列表将没有路径信息的前缀。请记住,可以使用 "basename" 可执行程序来除去前面的路径信息,如下所示:

 
 for x in /var/log/*
 do
     echo `basename $x` is a file living in /var/log
 done
 


当然,在脚本的命令行自变量上执行循环通常很方便。这里有一个如何使用本文开始提到的 "$@" 变量的例子:

 
 #!/usr/bin/env bash
 
 for thing in "$@"
 do
     echo you typed ${thing}.
 done
 
 
        输出:
 
 $ allargs hello there you silly
 you typed hello.
 you typed there.
 you typed you.
 you typed silly.
      

关于bash阶截断字符:

$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg

这样说可能会令人十分困惑,下面以一简单方式记住这个功能。当搜索最长匹配时,使用 ##(因为 ## 比 # 长)。当搜索最短匹配时,使用 #。看,不难记吧!等一下,怎样记住应该使用 '#' 字符来从字符串开始部分除去?很简单!注意到了吗:在美国键盘上,shift-4 是 "$",它是 bash 变量扩展字符。在键盘上,紧靠 "$" 左边的是 "#"。这样,可以看到:"#" 位于 "$" 的“开始处”,因此(根据我们的记忆法),"#" 从字符串的开始处除去字符。您可能要问:如何从字符串末尾除去字符。如果猜到我们使用美国键盘上紧靠 "$" 右边 的字符 ("%),那就猜对了。这里有一些简单的例子,解释如何截去字符串的末尾部分:

$ MYFOO="chickensoup.tar.gz"
$ echo ${MYFOO%%.*}
chickensoup
$ echo ${MYFOO%.*}
chickensoup.tar
 
正如您所见,除了将匹配通配符从字符串末尾除去之外,% 和 %% 变量扩展选项与 # 和 ## 的工作方式相同。请注意:如果要从末尾除去特定子字符串,不必使用 "*" 字符:

MYFOOD="chickensoup"
$ echo ${MYFOOD%%soup}
chicken
 可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。试着在 bash 中输入以下行:

$ EXCLAIM=cowabunga
$ echo ${EXCLAIM:0:3}
cow
$ echo ${EXCLAIM:3:7}
abunga
 


这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。

应用字符串截断

现在我们已经学习了所有截断字符串的知识,下面写一个简单短小的 shell 脚本。我们的脚本将接受一个文件作为自变量,然后打印:该文件是否是一个 tar 文件。要确定它是否是 tar 文件,将在文件末尾查找模式 ".tar"。如下所示:


mytar.sh -- 一个简单的脚本
#!/bin/bash
if [ "${1##*.}" = "tar" ]
then
    echo This appears to be a tarball.
else
    echo At first glance, this does not appear to be a tarball.
fi
 

 

用 uniq 除去重复行
    
        $ cat happybirthday.txt
Happy Birthday to You!
Happy Birthday to You!
Happy Birthday Dear Tux!
Happy Birthday to You!
        $ sort happybirthday.txt
Happy Birthday Dear Tux!
Happy Birthday to You!
Happy Birthday to You!
Happy Birthday to You!
        $ sort happybirthday.txt | uniq
Happy Birthday Dear Tux!
Happy Birthday to You!
 

 

 

二、vim一些命令

参考资料:vim_user_manual_603.0.pdf

 

vi有用的编程命令
ctrl+p 或 ctrl+n   自动补全
CTRL-X CTRL-F      补全文件名
iabbrev ad advertisement  缩写替代(可以用iab)
abbreviate teh the        输入更正
set textwidth=30         断行
{range}center [width]    对齐,还可以是right/left,如1,5center 40
vim -e -s $file < change.vim   shell中使用vim脚本
大小写忽略的搜索使用/c,/C是大小写敏感
要打开一个预览窗口显示函数"write char"的定义使用命令::ptag write_char
要关闭该预览窗口, 使用命令::pclose
[I 查找全局定义

将外部程序的输出包含在文件中
有时你会遇到想把某个命令的执行输出包含在文件中的情况,这是使用vim的 r!命令就可以很方便地做到。下面的命令将ls /home/的输出包含到文件中的当前位置:

:r!ls /home

 

将制表符转为空格:
:set expandtab
:%retab


vimdiff 查看两个文件的不同(注意,在shell下执行vimdiff)
1. Ctrl-w K(把当前窗口移到最上边)
2. Ctrl-w H(把当前窗口移到最左边)
3. Ctrl-w J(把当前窗口移到最下边)
4. Ctrl-w L(把当前窗口移到最右边)
ctrl-w w  改变编辑文件
:set noscrollbind
]c 跳到下一差异
文件比较的最终目的之一就是合并,以消除差异。如果希望把一个差异点中当前文件的内容复制到另一个文件里,可以使用命令
dp (diff "put")
如果希望把另一个文件的内容复制到当前行中,可以使用命令
do (diff "get",之所以不用dg,是因为dg已经被另一个命令占用了)
如果希望手工修改某一行,可以使用通常的vim操作。如果希望在两个文件之间来回跳转,可以用下列命令序列:
Ctrl-w, w

 


vi有用的快捷按键
有一些快捷按键对程序员而言特别有用, 下面是其中的一部分:
在函数中移动
List
[ [ = 移动到前一个行首的'{'字符上, 等价于?^{
] ] = 移动到下一个行首的'{'字符上, 等价于/^{
[ ] = 移动到前一个行首的'}'字符上, 等价于?^}
] [ = 移动到下一个行首的'}'字符上, 等价于?^}
[ #  = "#if"-"#endif"跳到开头
类似的有注释内的移动 [/ ,括号[(等
{ = 到前一个空行上
} = 到下一个空行上
gd = 到当前局部变量的定义处(当前的意思是光标停留其上的单词).
* = 到与当前单词相同的下一个单词上
# = 到与当前单词相同的上一个单词上
'' = 到上次光标停靠的行
括号匹配:
% 可以让光标从它当前所在的括号跳转到与它相匹配的括号上去, 对花括
号和圆括号, 方括号都有效, 常用于手工检查括号是否匹对.
替换操作:
Vim具有强大的字符串替换功能, 操作起来十分简单, 不需惹人生厌
的GUI(图形用户界面), 查找并替换文本, 可以使用下面的命令:
ex command
: [address] s//string/[g|c|N] (where N is an integer value).
(其中的N是一个整数值).
此命令查找由grep风格的正则表达式指定的匹配模式, 并将其替换为
由string指定的字符串, "address", "g", 和"N" 是对命令的补充选项,
它们分别决定了命令的作用范围, 是只替换第一个匹配的字符串还是替换
所有匹配的字符串, 只替换每行中第N次匹配的字符串1:
List
g = 全部: 替换每行中所有匹配的字符串.
c = 询问: 在每次替换之前询问用户是否确定要进行替换.
N = Nth 只替换该行第N次匹配
(不作指定时隐含为N=1, 替换该行的第一个匹配)
(即等价于address1, address2s//string/1)
1译者注: (a)如果没有指定这些辅助修饰标志, 则vim默认为只替换一行中第一个匹
配的字符串. (b) 据我所知, 只有ed行编辑器才有这种品性, ex与vi都没有这个选项
409
410 附录三用Vim进行C/C++编程介绍
List
[address values] --- 可以是一个或是由逗号分开的两个指定行范围的标识符.
(下面的x代表一个整数)
. = 表示当前行(即光标所在的行, 译者注)
$ = 当前文件的最后一行
% = 整个文件(即对每一行, 等价于1,$, 译者注)
x = 当前文件的第x行
+x = 从当前行开始下面的第x行(如果当前行为第1行, 则+3 代表第4行)
-x = 从当前行开始上面的第x行(如果当前行为第4行, 则-3 代表第1行)
逗号用于分隔任何上面指定的单个行, 以形成一个范围(当然, 这个
范围的下界不能小于上界, 如10,1为非法的范围, 此时vim会给出一个警
告信息, 问你是否进行反向操作, 如回答y, 则等价于1,10, 操作仍正常
进行, 否则, 撤消当前操作, 译者注), 其后指定的操作将作用于此处给
出的范围, vim帮助里有关于替换操作的充分信息.


"."命令可以重复最近一次的编辑动作. 但是如果你要做的操作远比
这些小儿科复杂呢? 那就是Vim为什么要引入命令记录的原因. 使用命令
记录分三个步骤1
1. 使用"qfregisterg"命令开始, 后续的动作将被记录进名为fregisterg的
寄存器中. 给出的寄存器名字必需是a到z之间的一个字母2
2 执行你要执行的操作3.
3. 按下q以结束对命令的记录(注意仅仅是q一个字符, 不要键入多
余的字符).
现在你可以通过"@frecordingg"命令来执行刚刚记录下来的记录宏
了.

 

 

 

 

三、GNU make技巧

参考资料:gnu-make-doc-zh_CN-1.3.pdf

 

If you want make to simply ignore a makefile which does not exist and cannot be remade,
with no error message, use the -include directive instead of include, like this:
-include filenames...

Within a command script (if the line begins with a TAB character) the entire line
is passed to the shell, just as with any other line that begins with a TAB. The shell
decides how to interpret the text: whether or not this is a comment is up to the shell.

Wildcard expansion does not happen when you define a variable. Thus, if you write this:
objects = *.o
then the value of the variable objects is the actual string ‘*.o’. However, if you use the
value of objects in a target, prerequisite or command, wildcard expansion will take place
at that time. To set objects to the expansion, instead use:
objects := $(wildcard *.o)

通常规则的语法格式如下:
TARGETS : PREREQUISITES
COMMAND
...
或者:
TARGETS : PREREQUISITES ; COMMAND
COMMAND


可以使用“$(patsubst %.c,%.o,$(wildcard *.c))”,首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。


规则命令行中的自动化变量“$^”代表所有通过目录搜索得到的依赖文件的完整路径名(目录 + 一般文件名)列表。“$@”代表规则的目标。自动化变量“$<”代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件。


静态模式规则是这样一个规则:规则存在多个目标,并且不同的目标可以根据目标文件的名字来自动构造出依赖文件。首先,我们来看一下静态模式规则的基本语法:
TARGETS ...: TARGET-PATTERN: PREREQ-PATTERNS ...
COMMANDS
“TAGET-PATTERN”和“PREREQ-PATTERNS”说明了如何为每一个目标文件生成依赖文件。从目标模式(TAGET-PATTERN)的目标名字中抽取一部分字符串(称为“茎”)。使用“茎”替代依赖模式(PREREQ-PATTERNS)中的相应部分来产生对应目标的依赖文件。
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
例子中,规则描述了所有的.o文件的依赖文件为对应的.c文件,对于目标“foo.o”,取其茎“foo”替代对应的依赖模式“%.c”中的模式字符“%”之后可得到目标的依赖文件“foo.c”
如果存在一个文件列表,其中一部分符合某一种模式而另外一部分符合另外一种模式,这种情况下我们可以使用“filter”函数(可参考 第八章 make的内嵌函数)来对这个文件列表进行分类,在分类之后对确定的某一类使用模式规则。例如:
files = foo.elc bar.o lose.o
$(filter %.o,$(files)): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte-compile $<


Makefile中,一个目标可以出现在多个规则中。但是这些规则必须是同一类型的规则,要么都是普通规则,要么都是双冒号规则。而不允许一个目标同时出现在两种不同类型的规则中。
当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。
Newprog :: foo.c
$(CC) $(CFLAGS) $< -o $@
Newprog :: bar.c
$(CC) $(CFLAGS) $< -o $@

 

make在执行命令行之前会把要执行的命令行输出到标准输出设备。我们称之为“回显”,就好像我们在shell环境下输入命令执行时一样。
但是,如果规则的命令行以字符“@”开始,则make在执行这个命令时就不会回显这个将要被执行的命令。典型的用法是在使用“echo”命令输出一些信息时。如:
@echo 开始编译XXX模块......
执行时,将会得到“开始编译XXX模块......”这条输出信息。如果在命令行之前没有字符“@”,那么,make的输出将是:
echo编译XXX模块......
编译XXX模块......


在Makefile中书写在同一行中的多个命令属于一个完整的shell命令行,书写在独立行的一条命令是一个独立的shell命令行。因此:在一个规则的命令中,命令行“cd”改变目录不会对其后的命令的执行产生影响。就是说其后的命令执行的工作目录不会是之前使用“cd”进入的那个目录。如果要实现这个目的,就不能把“cd”和其后的命令放在两行来书写。而应该把这两条命令写在一行上,用分号分隔。这样它们才是一个完整的shell命令行。如:
foo : bar/lose
cd bar; gobble lose > ../foo
如果希望把一个完整的shell命令行书写在多行上,需要使用反斜杠(/)来对处于多行的命令进行连接,表示他们是一个完整的shell命令行。


为了避免“递归展开式”变量存在的问题和不方便。GNU make支持另外一种风格的变量,称为“直接展开”式。这种风格的变量使用“:=”定义。在使用“:=”定义变量时,变量值中对其他量或者函数的引用在定义变量时被展开(对变量进行替换)。所以变量被定义后就是一个实际需要的文本串,其中不再包含任何变量的引用。


GNU make中,还有一个被称为条件赋值的赋值操作符“?=”。被称为条件赋值是因为:只有此变量在之前没有赋值的情况下才会对这个变量进行赋值.


在Makefile中使用“+=”(追加方式)来实现对一个变量值的追加操作。

 

 

 

四、强大的正则表达式(Reg expr)基础和Grep

 

POSIX Basic Regular Expressions
Traditional Unix regular expression syntax followed common conventions but often differed from tool to tool. The IEEE POSIX Basic Regular Expressions (BRE) standard (released alongside an alternative flavor called Extended Regular Expressions or ERE) was designed mostly for backward compatibility with the traditional syntax but provided a common standard which has since been adopted as the default syntax of many Unix regular expression tools, though there is often some variation or additional features. Many such tools also provide support for ERE syntax with command line arguments.

In the BRE syntax, most characters are treated as literals — they match only themselves (i.e., a matches "a"). The exceptions, listed below, are called metacharacters or metasequences.

. Matches any single character (many applications exclude newlines, and exactly which characters are considered newlines is flavor, character encoding, and platform specific, but it is safe to assume that the line feed character is included). Within POSIX bracket expressions, the dot character matches a literal dot. For example, a.c matches "abc", etc., but [a.c] matches only "a", ".", or "c".
[ ] A bracket expression. Matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", and "z", as does [a-cx-z].
The - character is treated as a literal character if it is the last or the first character within the brackets, or if it is escaped with a backslash: [abc-], [-abc], or [a/-bc].
 
[^ ] Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". As above, literal characters and ranges can be mixed.
^ Matches the starting position within the string. In line-based tools, it matches the starting position of any line.
$ Matches the ending position of the string or the position just before a string-ending newline. In line-based tools, it matches the ending position of any line.
/( /) Defines a marked subexpression. The string matched within the parentheses can be recalled later (see the next entry, /n). A marked subexpression is also called a block or capturing group.
/n Matches what the nth marked subexpression matched, where n is a digit from 1 to 9. This construct is theoretically irregular and was not adopted in the POSIX ERE syntax. Some tools allow referencing more than nine capturing groups.
* Matches the preceding element zero or more times. For example, ab*c matches "ac", "abc", "abbbc", etc. [xyz]* matches "", "x", "y", "z", "zx", "zyx", "xyzzy", and so on. /(ab/)* matches "", "ab", "abab", "ababab", and so on.
/{m,n/} Matches the preceding element at least m and not more than n times. For example, a/{3,5/} matches only "aaa", "aaaa", and "aaaaa". This is not found in a few, older instances of regular expressions.

转义的"尖括号" -- /<.../> -- 用于匹配单词边界.
Examples:

.at matches any three-character string ending with "at", including "hat", "cat", and "bat".
[hc]at matches "hat" and "cat".
[^b]at matches all strings matched by .at except "bat".
^[hc]at matches "hat" and "cat", but only at the beginning of the string or line.
[hc]at$ matches "hat" and "cat", but only at the end of the string or line.

[edit] POSIX Extended Regular Expressions
The meaning of metacharacters escaped with a backslash is reversed for some characters in the POSIX Extended Regular Expression (ERE) syntax. With this syntax, a backslash causes the metacharacter to be treated as a literal character. Additionally, support is removed for /n backreferences and the following metacharacters are added:

? Matches the preceding element zero or one time. For example, ba? matches "b" or "ba".
+ Matches the preceding element one or more times. For example, ba+ matches "ba", "baa", "baaa", and so on.
| The choice (aka alternation or set union) operator matches either the expression before or the expression after the operator. For example, abc|def matches "abc" or "def".

Examples:

[hc]+at matches "hat", "cat", "hhat", "chat", "hcat", "ccchat", and so on, but not "at".
[hc]?at matches "hat", "cat", and "at".
cat|dog matches "cat" or "dog".
POSIX Extended Regular Expressions can often be used with modern Unix utilities by including the command line flag -E.


[edit] POSIX character classes
Since many ranges of characters depend on the chosen locale setting (i.e., in some settings letters are organized as abc...zABC...Z, while in some others as aAbBcC...zZ), the POSIX standard defines some classes or categories of characters as shown in the following table:

POSIX ASCII Description
[:alnum:] [A-Za-z0-9] Alphanumeric characters
[:alpha:] [A-Za-z] Alphabetic characters
[:blank:] [ /t] Space and tab
[:cntrl:] [/x00-/x1F/x7F] Control characters
[:digit:] [0-9] Digits
[:graph:] [/x21-/x7E] Visible characters
[:lower:] [a-z] Lowercase letters
[:print:] [/x20-/x7E] Visible characters and spaces
[:punct:] [!"#$%&'()*+,-./:;<=>?@[///]_`{|}~] Punctuation characters
[:space:] [ /t/r/n/v/f] Whitespace characters
[:upper:] [A-Z] Uppercase letters
[:xdigit:] [A-Fa-f0-9] Hexadecimal digits

POSIX character classes can only be used within bracket expressions. For example, [[:upper:]ab] matches the uppercase letters and lowercase "a" and "b".

In Perl regular expressions, [:print:] matches [:graph:] union [:space:]. An additional non-POSIX class understood by some tools is [:word:], which is usually defined as [:alnum:] plus underscore. This reflects the fact that in many programming languages these are the characters that may be used in identifiers. The editor Vim further distinguishes word and word-head classes (using the notation /w and /h) since in many programming languages the characters that can begin an identifier are not the same as those that can occur in other positions.

Note that what the POSIX regular expression standards call character classes are commonly referred to as POSIX character classes in other regular expression flavors which support them. With most other regular expression flavors, the term character class is used to describe what POSIX calls bracket expressions.

 

 

grep例子:

$ grep '[a-z]/{5/}' aa

显示所有包含每个字符串至少有5个连续小写字符的字符串的行。

 

 

五、查找代码文本和文件必备--find命令和xargs

基本格式:
find pathname -options [-print -exec -ok ...]

find命令的参数;
pathname: find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。
-print: find命令将匹配的文件输出到标准输出。
-exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' {  } /;,注意{   }和/;之间的空格。
-ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。


find命令选项
-name

按照文件名查找文件。

-perm
按照文件权限来查找文件。

-prune
使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。

-user
按照文件属主来查找文件。

-group
按照文件所属的组来查找文件。

-mtime -n +n
按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。

-nogroup
查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。

-nouser
查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
-newer file1 ! file2

查找更改时间比文件file1新但比文件file2旧的文件。
-type

查找某一类型的文件,诸如:

b - 块设备文件。
d - 目录。
c - 字符设备文件。
p - 管道文件。
l - 符号链接文件。
f - 普通文件。

-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。

-mount:在查找文件时不跨越文件系统mount点。
-follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。
-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。


忽略某个目录:
find . -path "./*tool*" -prune -o -name "*.o"  -print


关于exec:
find logs -type f -mtime +5 -exec rm {  } /;

 

关于xargs:
在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。

find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。

在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;

而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

find . -name "file*" -print | xargs echo "" > /temp/core.log

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值