记录学习过程中的点点滴滴
shell编程
awk中ord的实现:将字符转化对应的ascii码
六 14th
在awk中并未直接提供ord函数,所以在将某个字符转换为码时,需要自己来实现
awk 'BEGIN{for (i = 0; i < 256; ++i) {ord[sprintf("%c", i)] = i;} }' ' { print ord['a']; ord ['b']; }'
这里主要是构造了ord为key,val的数据结构,key为char字符,val对应的ascii码
awk学习笔记之正则表达式
六 7th
正则在Awk中用处比较多,这里就其主要用法做个大概的介绍。
- 使用正则
awk中的regexp是用斜线包括,如/xx/, 就是一个比较简单的正则
awk '/foo/ {print $2}'
上面的示例是每行的记录只要包括foo字符串的,就将其第二个字段打印
注:/foo/ : 是指只要记录包含子串即可,不管其出现的位置
- 两种匹配方式~ !~
- str ~ /regexp/ str匹配正则表达式时,返回true
- str !~ /regexp/ str不匹配正则表达式时,返回true
- 正则中的转义字符
对于一些非可打印的字符,使用\进行转义。
如 \t : 代表tab \\ 代表\, \*代表* - 正则中使用的operator
- ^ : 头部开始匹配
如^Sep : 则str必须以Sep开头,正则匹配才会返回true - $ : 尾部匹配
如end$ : 则str必须以end结尾,则正匹配才会返回true - . : 匹配任意的字符
- [...] : 匹配[]包含字符的某一个
如[0-9] 匹配任意的一个数字
[a-zA-Z] 匹配任意的字母
[MVX] 匹配字符’M’ ‘V’ ‘X’中的某一个
内置的表示:[:alnum:] 代表所有的字母和数字,
[:alpha:] 代表所有的字母 [:digit:] 代表所有的数字
- [^...] : 中括号中加入^, 匹配非[]内的所有字符
- | : 或的关系,^P | [0-9] 匹配所有的以P开头的字符串,或者包含数字的字符串
注:| 的优先级最低 - () : 将正则括起来
- 出现次数的operator: * + ? {m,n}
- ^ : 头部开始匹配
- awk的正则匹配是大小写敏感,可使用tolower(str) ~ /regexp/
awk学习笔记【一】
六 4th
今天主要介绍下awk中内置的String函数和awk中内置的变量。
awk中内置的string函数
- index(in, find): 在 string “in”中查找 find 的第一次出现位置,返回的find在in中第一个字符出现的位置,从1开始
awk 'BEGIN { print index("peanut", "an") }' # 打印3
- length(string) : 返回字符串的长度,如果是number类型,返回对应字符的长度
- match(string, regexp) : 正则匹配regexp的规则,如果匹配,则返回对应第一个字符的位置
- split(string, array, fieldsep) : 按照fieldsep分割字符串,并将结果放置到array中,array的下标从1开始
split("yaronspace.cn", fields, ".") # fields[1] = "yaronspace" # fields[2] = "cn"
- sprintf(format, expression1, …): 格式化字符串
- sub(regexp, replacement, target): 将第一个匹配的regexp的部分使用replacement替代,替代后的结果还是保存在target变量中。所以target必须是变量,不可为字符常量
str = "yaronspace.cn"; sub(/yaronspace/, "xiaofangdeng", str); # str="xiaofengdeng.cn"
使用&符号引用匹配regexp部分的字符长,示例如下:
str = "yaronspace.cn"; sub(/yaronspace/, "&_xiaofangdeng", str); # str = "yaronspace_xiaofangdeng.cn"
- gsub(regexp, replacement, target): 与sub功能类似,但是会替换所有匹配regexp的子串,g代表”global”的含义
- substr(string, start, length) : 获取子串
- tolower(string) : 转化为小写
- toupper(string) : 转化为大写
awk中内置的变量
- FS: Input Field Seperator variable: 对每行记录的分割符,可以通过-F参数修改,或者在awk文件中,直接使用FS=”XX”进行修改
- OFS : Output Field Seperator variabble: 输出时默认每个记录的分隔符,默认为空格
$ awk -F':' '{print $3,$4;}' /etc/passwd # $3 $4以空格分割 $ awk -F':' 'BEGIN{OFS="_"} {print $3, $4}' # 此时$3 $4是以_分割
- RS : Input Record Seperator variable: 记录的默认分隔符,默认为\n换行符
可以修改,如将其修改为\n\n,以两个空行为分隔符 - ORS: Ouput Record Seperator variable: 默认的记录的输出的分隔符,默认为\n
- NR: Number of records variable: 当前已读取记录数,默认情况为当前的行数
- NF: Number of fields vairable : 当前记录的域的个数
- FILENAME : Name of the current input file
- FNR: Number of Records relative to the current input file : 当awk的输入文件只有一个时,NR == FNR;当awk的输入文件时多个时,FNR是当前文件的当前行数,NR是全局的行数
参考文章:
1. http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_92.html
使用Bash中Complete自动补全命令
十二 25th
大家在Linux下都用shell的TAB自动补全功能,非常方便,但是有时自己开发程序,可能需要自定义实现TAB自动补全功能,这时可能就会用到complete命令来实现对命令的自定义补全,本文主要介绍complete的用法,下一篇会着重介绍对ssh的自动补全的实现。
入门
首先先看一个非常简单的例子:
$ # Create a dummy command: $ touch ~/bin/myfoo $ chmod +x ~/bin/myfoo $ # Create some files: $ touch a.bar a.foo b.bar b.foo $ # Use the command and try auto-completion. $ # Note that all files are displayed: $ myfoo <TAB><TAB> a.bar a.foo b.bar b.foo $ # Now tell bash that we only want foo files. $ # This command tells bash args to myfoo are completed $ # by generating a list of files and then excluding $ # everything # that doesn't match *.foo: $ complete -f -X '!*.foo' myfoo $ # Tray again: $ myfoo <TAB><TAB> a.foo b.foo
- 首先自定义了command: myfoo, 然后测试对myfoo的自动补全功能,默认情况下,myfoo会自动列出当前目录的文件作为自动补全
内容 - complete -f -X ‘!*.foo’ myfoo : 使用complete命令对myfoo自定义补全功能,参数含义:-f 是列出当前的文件 -X pattern 将符合pattern条件的文件exclude,这里主要是显示*.foo的文件,将*.bar文件排除在外
complete参数详解
complete [-abcdefgjksuv] [-o comp-option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] name [name ...]
- -W wordlist: 自动补全使用的wordlist, 使用IFS分割,会和当前用户输入的Word做前缀比较,提示那些匹配的word list.
- -S suffix: 向每个自动补全word后添加suffix 后缀.
- -P prefix: 向每个自动补全word后添加prefix 前缀.
- -X filterpat: 对于文件名,将匹配pattern的文件名从completion list中移除(exclude), pattern中使用!表示否定
- -G globpat: 对于文件名,将匹配pattern的文件名作为可能的completion. 与-X刚好相反,-X “!*.foo” 与 -G “*.foo”作用相同
- -C command: 将command命令的执行结果作为可能的completion.
- -F function: 执行shell function,在function中对COMPREPLY这个数组复制,作为可能的completion
- -p [name]: 打印当前自定义的complete
- -r [name]: 删除当前自定的complete
- -A action : 表示生成可能的completion的方式,包括alias, file, directory等,具体请参看文后的参看资料
使用样例
- 使用-C -G -X参数
complete -C "pwd" ls # ls的自动补全为当前目录 complete -G "*.py" ls # ls的自动补全为.py文件 complete -X "*.py" ls # ls的自动补全为非.py文件
-
使用-F 参数自定义补全函数
function _mycomplete_() { local cmd="${1##*/}" # 当前命令 local word=${COMP_WORDS[COMP_CWORD]} #当前输入的字符串 local line=${COMP_LINE} #整行字符串 local xpat='*.py' # pattern # 根据word的值来补全当前非.py的文件file. COMPREPLY=($(compgen -f -X "$xpat" -- "${word}")) } # _mycomplete_函数可定义在.bash_profile中,然后执行 source ~/.bash_profile # 当然也可多个命令共用一个function, 只要_myfunction_作区分即可,比如对cmd执行case语句 # 生成不同的xpat complete -F _mycomplete_ myfoo #使用_mycomplete 作为myfoo的自动补全
参考资料
Linux中关于Cache Memory的介绍
十 19th
最近在做性能优化时,遇到一个问题,系统中进程占用的内存没有那么多,但是通过TOP看到系统对实际物理内存接近满额,十分纳闷,后来问了同事
才知道原来是Cache Memory占用了大量内存,上网查阅了相关资料,整理记录下。
什么是Cache Memory
当进程对磁盘中的文件大量读写时,Linux内核为了提升读写性能,会将文件在内存中进行缓存,这部分内存就是Cache Memory(缓存内存)。即使你的程序运行结束后,Cache Memory也不会自动释放。这就会导致你在Linux系统中程序频繁读写文件后,你会发现可用物理内存会很少。
如何释放Cache Memory(缓存内存):
用下面的命令可以释放Cache Memory:
To free pagecache:
echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes:
echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
echo 3 > /proc/sys/vm/drop_caches
free命令介绍
total used free shared buffers cached
Mem: 16425996 10727220 5698776 0 380904 9389832
-/+ buffers/cache: 956484 15469512
Swap: 8273464 212 8273252
其中第一行用全局角度描述系统使用的内存状况:
total——总物理内存
used——已使用内存,一般情况这个值会比较大,因为这个值包括了cache+应用程序使用的内存
free——完全未被使用的内存
shared——应用程序共享内存
buffers——缓存,主要用于目录方面,inode值等(ls大目录可看到这个值增加)
cached——缓存,用于已打开的文件
另外这里有一篇taobao的大牛对memory使用的介绍,很详细:http://blog.yufeng.info/archives/2456
Linux下禁用Swap的方法
1. swapoff -a : 禁用swap空间
2. swapon -a : 开启swap空间
[shell学习笔记]sort、uniq、cut、paste和split用法详解
八 24th
今天学习了sort, uniq, cut, paste和split命令的用法,其中sort的选项比较多一些,其它的命令就比较简单了
关于sort,本站之前写过一篇关于sort的高级用法,请点击这里
一、Sort命令
sort [OPTION]… [FILE]…
对文件按指定的域进行排序
常用选项:
- -c: 检测文件是否已经排序
- -m: 将两个已经排序的文件进行合并
- -u: 在排序过程中,删除重复的行
- -o: 保存排序后的文件
- -t: 域分隔符,默认为空格和tab
- -n: 指定待排序的域为数字类型
- -r: 逆序排序,默认为正向排序
- -b: 按域排序时忽略第一个空格
- +n: 按照第n个域进行排序,域从第0个开始计数
- +m.n: 按照第m个域的第n个字符开始开始排序
- -k: 按照第k个域进行排序,域从第1个开始计数
常见的用法例子:
sort -o output.txt your_file.txt #对文件按第一域进行排序,将排序结果保存到output.txt sort -t: -r +2n your_file.txt #对文件按照第2个域进行逆向排序,第二个域为数字类型,同时分割符为: df | sort -b -r -k5 #按照磁盘的占用率从高到底进行排序输出
二、uniq命令
uniq [OPTION]… [INPUT [OUTPUT]]
从文件中去除或删除重复的行,在功能上和sort -u类似
常用选项:
- -u: 只显示不重复的行
- -d: 只显示重复的行
- -c: 打印每一行出现的次数
- -fn: 忽略前n个域
常用的用法例子:
uniq sort_file.txt #删除文件中重复的行 uinq -c sort_file.txt #显示每行出现的次数 uinq -d sort_file.txt #只显示出现次数>=2的行
三、join命令
join [OPTION]… FILE1 FILE2
将两个排序的文件合并为一个文件
常用选项:
- -j n m: 选择连接的域,n为文件号,m为域号
- -o n.m : 指定显示的域,n为文件号,m为域号
- -an: 显示文件n中不匹配的文件行
- -t: 定义分隔符
常见的用方法:
join sort_file1.txt sort_file2.txt #合并两个文件,以第一个键排序 join -j 1 1 -j 2 2 sort_file1.txt sort_file2.txt #按第一文件的第一个域和第二个文件的第二个域作为key,进行合并 join -o 1.1 , 2.2 sort_file1.txt sort_file2.txt #只显示第一个文件的第一个域和第二个文件的第二个域
四、cut命令
cut OPTION… [FILE]…
从文件中获取指定域
常用选项:
- -d: 分割符
- -f: 输出域的编号
- -c: 输出字符的编号
常见的用法:
cut -d: f3 file.txt #输出以:分割的第三个域 cut -d: f 1, 6 file.txt #输出以:分割的第一个和第六个域 ls -al | cut -c1-3 #显示ls输出每行的前三个字符
五、paste命令
paste [OPTION]… [FILE]…
将文件的行进行merge
常用选项:
- -d: 指定两个文件的行合并后的分割符
- -s: 将每个文件合并为一行,而不是按行进行合并
常见用法:
paste file1 file2 #将两个文件的每行合并 paste -d: file1 file2 #将两个文件的每行合并,分隔符为: paste -s file1 file2 #将file1的内容合并为一行,将file2的内容合并为一行
六、split命令
split [OPTION]… [INPUT [PREFIX]]
将文件按大小分为多份
常用选项:
- -output_file-size: 指定文件被分割的行数
- prefix: 输出文件的前缀
常见用法:
split -20 file #将文件每20行进行一次分割
[shell学习笔记]grep和find命令详解
八 13th
最新在看《Linux And Unix shell Programing 》,避免看完之后忘记,以后每看一部分都记录下。今天主要记录下linux下
最常用的两个命令grep和find。
一、Grep命令
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
查找文件中包含某个关键词的行;
常用选项:
- -c : 只输出匹配的行数
- -i : 查找不区分大小写
- -n: 显示匹配的行号
- -v: 显示不包含关键词的行
- -A Num: 显示匹配的行及其后面num行
- -B Num: 显示匹配的行及其前面的num行
- -r: 如果遇到目录递归查询
- -E :正则表达式扩展
常见的用法
grep keyword -r * # 在当前目录及其子目录下查找包含keyword的行 grep --exclude="*\.svn*" keyword -r * #功能同上,但是不查找.svn文件 #正则表达式 grep ‘48[34]’ your_file #查找包含483或者484的行 grep '4\{3,8\}' your_file #查找包含3个到8个4的行 grep -E '216|329' your_file #包含216或者329的行 #和其它程序配合使用 ps aux | grep apache2 | grep -v grep #查找apache2相关进程
二、Find命令
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
在目录中查找文件
常用选项:
- -name: 按照文件名来查找
- -type: 按照文件类型查找(b: block d: directory )
- -perm: 按照权限来查找
- -user: 按照文件属主来查找
- -group: 按照组来查找
- -mtime +n -n: 按照修改时间来查找,-n代表n天以内的修改的文件,+n代表n天以前的修改的文件
- -newer fil1 !file2 : 查找比file1新的文件,但是比file2旧的文件
- -size n c: 按照文件大小查找,带c表示以字节计算
- -exec: 当匹配到文件后,执行某些命令,该命令以 {} \;结束,如果在执行命令前需要确认,请加-ok选项
常见的用法
find . -name "*.txt" -print #在当前目录及其子目录中查找以.txt文件为后缀的文件 find . -type d -print #查到当前目录中的目录文件 find . -mtime +5 -name "*.log" -exec rm {} \; #删除5天前得日志 find . -mtime +5 -name "*.log" -ok rm {} \; #功能同上,但是删除前会确认
近期评论