grep 正则匹配

grep命令

功能:输入文件的每一行中查找字符串。

基本用法:

grep [-acinv] [--color=auto] [-A n] [-B n] '搜寻字符串' 文件名
参数说明:
-a:将二进制文档以文本方式处理
-c:显示匹配次数
-i:忽略大小写差异
-n:在行首显示行号
-A:After的意思,显示匹配字符串后n行的数据
-B:before的意思,显示匹配字符串前n行的数据
-v:显示没有匹配行-A:After的意思,显示匹配部分之后n行-B:before的意思,显示匹配部分之前n行
--color:以特定颜色高亮显示匹配关键字

     –color选项是个非常好的选项,可以让你清楚的明白匹配了那些字符。最好在自己的.bashrc或者.bash_profile文件中加入:

alias grep=grep --color=auto

     每次grep搜索之后,自动高亮匹配效果了。

     ‘搜寻字符串’是正则表达式,注意为了避免shell的元字符对正则表达式的影响,请用单引号(’’)括起来,千万不要用双引号括起来(””)或者不括起来。

     正则表达式分为基本正则表达式和扩展正则表达式。下面分别简单总结一下。

基本正则表达式

     正则表达式学习,主要是对正则表达式元数据的学习。正则表达式本身没有什么高深的东西,本文仅仅对基本正则表达式的元数据进行一下总结:

元数据

意义和范例

^word 搜寻以word开头的行。例如:搜寻以#开头的脚本注释行

grep –n ‘^#’ regular.txt

 

word$ 搜寻以word结束的行例如,搜寻以‘.’结束的行

grep –n ‘.$’ regular.txt

 

. 匹配任意一个字符。例如:grep –n ‘e.e’ regular.txt

匹配e和e之间有任意一个字符,可以匹配eee,eae,eve,但是不匹配ee。

 

\ 转义字符。例如:搜寻’,’是一个特殊字符,在正则表达式中有特殊含义。必须要先转义。

grep –n ‘\” regular.txt

 

* 前面的字符重复0到多次。例如匹配gle,gogle,google,gooogle等等

grep –n ‘go*gle’ regular.txt

 

[list] 匹配一系列字符中的一个。例如:匹配gl,gf。

grep –n ‘g[lf]’ regular.txt

 

[n1-n2] 匹配一个字符范围中的一个字符。例如:匹配数字字符

grep –n ‘[0-9]’ regular.txt

 

[^list] 匹配字符集以外的字符例如:grep –n ‘[^o]‘ regular.txt

匹配非o字符

 

\{n1,n2\} 前面的字符重复n1,n2次例如:匹配google,gooogle。

grep –n ‘go\{2,3\}gle’ regular.txt

 

\<word 单词是的开头。例如:匹配以g开头的单词

grep –n ‘\<g’ regular.txt

 

word\> 匹配单词结尾例如:匹配以tion结尾的单词

grep –n ‘tion\>’ regular.txt

 

扩展正则表达式

     grep一般情况下支持基本正则表达式,可以通过参数-E支持扩展正则表达式,另外grep单独提供了一个扩展命令叫做egrep用来支持扩展正则表达式,这条命令和grep -E等价。虽然一般情况下,基本正则表达式就够用了。特殊情况下,复杂的扩展表达式,可以简化字符串的匹配。

     扩展正则表达式就是在基本正则表达式的基础上,增加了一些元数据。

元数据

意义和范例

+ 重复前面字符1到多次。例如:匹配god,good,goood等等字符串。

grep –nE go+d’ regular.txt

 

? 匹配0或1次前面的字符例如,匹配gd,god

grep –nE ‘go?d’ regular.txt

 

| 或(or)的方式匹配多个字串
例如:grep –nE ‘god|good’ regular.txt
匹配god或者good。

 

() 匹配整个括号内的字符串,原来都是匹配单个字符例如:搜寻good或者glad

grep –nE ‘g(oo|la)’ regular.txt

 

() 前面的字符重复0到多次。例如匹配gle,gogle,google,gooogle等等

grep –nE ‘go*gle’ regular.txt

 

     Linux下面正则表达式博大精深,上文支持总结了最常用的部分,如果熟练掌握的上面部分的正则表达式基本上可以满足日常使用了。

     另外Linux很多命令支持正则表达式,比如find,sed,awk等等。请在使用的时候参照这些命令的手册使用正则表达式。

 

常用命令:

递归替换所有php文件中所有字符串“UB_LOG_”为“LOG_”

sed -i s/UB_LOG_/LOG_/g `grep -lr ‘UB_LOG’ –include=”*.php” ./`

发表在 bash | 留下评论

Linux Bash Shell:流程控制——if/else(转载)

本文也即《Learning the bash Shell》3rd Edition的第五章Flow Control之读书笔记,但我们将不限于此。flow control是任何编程语言中很常用的部分,也包括了bash。在这里,我们将学习他们。

if/else是通过判断选择执行或者执行部分代码,可以根据变量、文件名、命令是否执行成功等很多条件进行判断,他的格式如下:

if condition
then
statements
[elif condition
then statements. ..]
[else
statements ]
fi

和 C程序不一样,bash的判断不是通过boolean,而是通过statement,也就是执行命令后的最终状态(exit status)。所有的Linux命令,无论你是代码是C还是脚本,执行完,都返回一个整数通知他的调用这,这就是exit status,通常0表示OK,其他(1-255)表示错误。这只是通常的情况,例如diff,0表示你no difference,1表示difference,2表示错误。if判断statements的最后一个的exit status,通常我们只放一个statement,如果为0,表示true,否则表示false。

执行下一条命令会冲掉原来exit status。可以使用$?来查看上一命令执行的结果。例如我们希望用一个新的cd命令来替代原来在linux kernel中已将编译的cd命令,由于function是优先于built-in命令,所以调用时,将调用我们的function。下面有一个例子,function pushd,在stack中键入cd的dirname路径名,并执行跳到该路径下。

cd ( )
{
#由于我们已经定义了具有更高优先级别的function,如果希望调用原来built-in的命令,需要再前面加上builtin。
builtin cd “$@”
#$?是上一command的返回值,即builtin cd “$@”的值,并记录在result里面。
result=$?
    echo “$OLDPWD –> $PWD”
#返回result的值。我们需要注意shell中的返回和在其他程序,例如C语言中的返回是不一样的,只代表最后的exit statue,而不是所谓的返回值,虽然也用到了return。如何没有最后的reture,例如后面的push_func,exit status就是最后执行的command的exit status
return   $result
}

push_func( )
{
dirname=$1
#如果dirname为null,退出funcuntion,如cd dirname成功,push the directory ,否则显示still in $PWD,cd使用function的cd函数,其优先级别高于已在内核编译了的cd
if cd ${dirname:?”missing directory name.”}
then
        mystack=”$dirname ${mystack:-$OLDPWD }”
echo $mystack
else
echo still in $PWD.
fi
}

push_func $1

条件结合

和C语言一样,可以进行条件结合,使用&&,||,以及!三种方式,表示“和”,“或”,与”非“,格式如下:if statement1 && statement2, ifstatement1 || statement2 ,if  statement1 。

exit status不是判断的唯一值,可以使用[...]和[[...]]。

字符串比较

字符串比较是放置在[...]中,有以下的几种:

 

  • str1 = str2,字符串1匹配字符串2
  • str1 != str2,字符串1不匹配字符串2
  • str1 > str2,字符串1大于字符串2
  • str1 < str2,字符串1小于字符串2
  • -n str,字符串不为null,长度大于零
  • -z str,字符串为null,长度为零

 

需要注意<和>符号和重定向符号相似,为了避免歧义和错误,使用if [ $a /> $b ] 的方式 。仍然上面的例子,我们增加pop_func来操作stack:

例如,我们要求命令带有参数,除了使用{1?”<message”}以外,下面给出更可读的方式:

if [ -z "$1" ]; then
echo ‘usage: c filename [-N]‘
exit 1
fi

在这里exit表示结束,退出,执行的结果为失败,非零。

文件属性比较

文件属性比较是另一个常用的条件判断类型。

 

  • -a   file :file 存在
  • -d file :file存在并是一个目录
  • -e file :file 存在,同- a
  • -f file :file 存在并且是一个常规的文件(不是目录或者其他特殊类型文件)
  • -r file :有读的权限
  • -s file :文件存在且不为空
  • -w file :有写的权限
  • -x file :有执行的权限,或者对于目录有search的权限
  • -N file :在上次读取后,文件有改动
  • -O file :own所属的文件
  • -G file :group所属的文件
  • file1 -nt file2 :file1 比 file2 更新,以最后更新时间为准
  • file1 -ot file2 :file1 比 file2 更旧 ,以最后更新时间为准

 

这些在[ ... ]中的条件判断是可以多个结合起来,例如if [ condition ] && [ condition ]; then,当然也可以if command && [ condition ]; then,不在类推。尤其我们可以进行复制的条件判断。另外还可以使用-a 和-o ,等同于C语言中的&和|的逻辑计算复符号,他们和&&即||相似。当他们用在condition里面。

在上面push_func的例子中,除了判断是否参数之外,增加判断是否是目录名,如下:

        if [ -n "$dirname" ] &&[ -d "$dirname" ]
then
cd $dirname
mystack=”$dirname ${mystack:-$OLDPWD }”
echo $mystack
else
echo still in $PWD.
fi

我们在增加一个判断,当时目录名的时候,在检查是否可以进行查看或操作。使用if [ -n "$dirname" ] &&[ -d "$dirname" -a -x "$dirname" ],但是这种写法很难阅读,我们需要将两个前后判断括起来,( -d “$dirname” ) -a ( -x “$dirname” )。但是(是个特殊符合,需使用/(的方式,即为:if [ -n "$dirname" ] &&[ /( -d "$dirname" /) -a /( -x "$dirname" /) ] 。

整数比较

>或者<或者=是用于字符串的比较,如果用于整数比较,使用:

 

  • -lt,小于
  • -le,小于等于
  • -eq,等于
  • -ge,大于等于
  • -gt,大于
  • -ne,不等于
发表在 bash | 留下评论

rsync同步机器文件

#!/bin/bash
#同步文件
from_dir=$1
to_dir=$2
sync_dryrun()
{
        fr=$1
        to=$2
        echo 
        echo -e "\033[1m ...dryrun... \033[0m"
        rsync -vr --delete ${fr} ${to} --dry-run --exclude='.svn/'
        echo -e "\033[1m ...dryrun... \033[0m"
        echo
}
sync_server()
{
        fr=$1
        to=$2
        echo 
        echo -e "\033[1m ...syncing... \033[0m"
        rsync -avr --progress --delete ${fr} ${to} --exclude='.svn/'
        echo -e "\033[1m ...done... \033[0m"
        echo
}

if [[ -z $from_dir ]] || [[ -z $to_dir ]]; then
        echo "Usage: $0 from_dir to_dir"
        exit 0;
fi

sync_dryrun $from_dir $to_dir
echo -n "Want to sync?(y/n):"
read R
if [ "${R:-y}" = "y" ];then
        sync_server $from_dir $to_dir
else
        echo "Nothing done,bye"
fi
发表在 bash | 留下评论

ssh传输免密(转载)

在Linux环境下,两台主机之间传输文件一般使用scp命令,通常用scp命令通过ssh获取对方linux主机文件的时候都需要输入密码确认。

不过通过建立信任关系,可以实现不输入密码。

这里假设A的IP:192.168.10.1

B的IP:192.168.10.2

需要从A免密码输入复制文件至B。
1. 在主机A上执行如下命令来生成配对密钥:
ssh-keygen -t rsa 
按照提示操作,注意,不要输入passphrase。提示信息如下
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
ff:8e:85:68:85:94:7c:2c:46:b1:e5:2d:41:5c:e8:9b  root@localhost.domain

2. 将 .ssh 目录中的 id_rsa.pub 文件复制到 主机B 的 ~/.ssh/ 目录中,并改名为  authorized_keys。
scp .ssh/id_rsa.pub 192.168.10.2:/root/.ssh/authorized_keys

以后从A主机scp到B主机就不需要密码了。

3.使用此方法需要注意:复制的两台计算机需要用相同的账户名,这里都是用的root。为了安全起见,需要在两台机器中创建相同的账号,然后在A上用su命令切换至账号下,执行第1步,第二步中复制文件时可能.ssh目录并不存在,需要手动创建。

在第2步中如果机器中已经存在authorized_keys文件,则需注意,这个文件可以包含多个SSH验证信息,这时可用 cat >>命令将验证文件内容附加上去。

比如复制到scp .ssh/id_rsa.pub 192.168.10.2:/root/.ssh/a.pub

然后执行cat ~/.ssh/a.pub >> ~/.ssh/authorized_keys

发表在 bash | 留下评论

给nginx添加一个简单的认证(转载)

http://www.ttlsa.com/nginx/nginx-basic-http-authentication/

发表在 nginx | 留下评论

cp 多个文件批量重命名(转载)

先说linux下批量复制并重命名,其实就是个for循环

以txt文件为例

命令行打入(F为变量名,可任意)

for F in *.txt ; do cp $F ${F%.txt}_1.txt;done

其中${F%.txt}_1.txt的意思是把F中得.txt去掉后加上_1.txt

想要每步骤都显示出来,在cp后面加上-vf 

如果这么写,就是批量改后缀,把txt改成ini后缀

for F in *.txt ; do mv $F ${F%.txt}.ini ;done

想要每步骤都显示出来,在mv后面加上-vf

扩展思维,一般排序都是首字符,所以想在文件名前面添加字符kk可以这么写

for F in *.txt ; do cp -vf $F (kk可为任意字符)kk$F ;done

再说

linux下批量复制文件到多个文件夹

mkdir建以1,2,3,4,5个文件夹名

把所有ini后缀的文件拷贝到12345文件夹得集合F中,命令如下

for F in 1 2 3 4 5 ;do cp *.ini $F ;done

想要每步骤都显示出来,在cp后面加上-vf

for F in 1 2 3 4 5;do cp -vf *.ini $F ;done

注意事项,所有命令如果遇到重名,会把以前得文件替换掉,慎重!慎重!

批量复制文件并改成有顺序的文件名

写shell脚本

i=0
F=a

while [ $i -le 10 ]
do
  cp -vf 00.ts $F$i.ts
  let i+=1
done

其中00.ts为源文件,批量复制10个

发表在 bash | 留下评论

vim取消复制粘贴时自动缩进

废话不多说

:set paste
转载自http://www.cnblogs.com/end/archive/2012/06/01/2531147.html
发表在 issues | 留下评论

archlinuxARM安装到树莓派

之前树莓派的系统安装需要img烧制到sd或tf卡上,archlinux比较特殊,不提供img文件,所以安装需要用linux环境复制文件到sd卡

1、给sd分区

fdisk /dev/sdX

输入 o 并回车,这将会删除所有分区
输入 p 并回车,这将会列出所有分区,此时应该没有任何分区
输入 n 并回车,创建新分区,引导分区
输入 p 并回车,新分区为主分区
输入 1 并回车,分区序号是1
按键盘回车,默认初始扇区
输入 +100M 并回车,设置终止扇区
输入 t 并回车,再输入 c 并回车,设置该分区文件系统格式为Fat32
输入 n 并回车,创建新分区,根分区
输入 p 并回车,新分区为主分区
输入 2 并回车,分区序号是2
按键盘回车,默认初始扇区
按键盘回车,默认终止扇区
输入 w 并回车,写入设置

mkfs.vfat /dev/sdX1

mkfs.ext4 /dev/sdX2

mkdir boot root

mount /dev/sdX1 boot

mount /dev/sdX2 root

2、wget并解压远程文件

wget http://mirrors.ustc.edu.cn/archlinuxarm/os/rpi/ArchLinuxARM-2015.11-rpi-2-rootfs.tar.gz -C root

sync

mv root/boot/* boot

umount boot root

从虚拟机释放sd,至此,就可以把sd插到树莓派上了,第一次使用需要用有线连接才能连接网络,ssh登陆用户名:root,密码:root

注:这儿有个问题,用ssh登录不上去,原因是由于OpenSSH更新引起的:默认情况下,不再允许root用户以密码方式ssh登录

解决方案:

The default for the sshd_config(5) PermitRootLogin option has changed from "yes" to "prohibit-password

用其它linux挂载该系统sd卡,修改/etc/ssh/sshd_config文件中的

PermitRootLogin prohibit-password => PermitRootLogin yes

发表在 linux | 留下评论

光标操作(转载)

ctrl键组合

  • Ctrl + f 光标向前(Forward)移动一个字符位置
  • Ctrl + b 光标往回(Backward)移动一个字符位置
  • Alt + f 光标向前(Forward)移动到下一个单词
  • Alt + b 光标往回(Backward)移动到前一个单词
  • Ctrl + a 光标移动到行首(Ahead of line),即Home键
  • Ctrl + e 光标移动到行尾(End of line),即End键
  • Ctrl + d 删除一个字符,即Delete键(命令行若无字符,相当于exit;处理多行标准输入时也表示EOF)
  • Ctrl + h 退格删除一个字符,即Backspace键
  • Ctrl + w 删除从光标位置前到当前所处单词的开头
  • Alt + d 删除从光标位置到当前所处单词的末尾
  • Ctrl + u 删除光标之前到行首的字符
  • Ctrl + k 删除光标之前到行尾的字符
  • Ctrl + c 取消当前行输入的命令,相当于Ctrl + Break
  • Ctrl + l 清屏,相当于执行clear命令
  • Ctrl + p 调出命令历史中的前一条(Previous)命令,即向上箭头键
  • Ctrl + n 调出命令历史中的下一条(Next)命令,即向下箭头键
  • Ctrl + r 显示:号提示,根据用户输入查找相关历史命令(reverse-i-search)
  • Ctrl + y 粘贴最后一次被删除的单词

esc组合
esc+d: 删除光标后的一个词
esc+f: 往右跳一个词
esc+b: 往左跳一个词
esc+t: 交换光标位置前的两个单词。

发表在 linux | 留下评论

chrome跨域设置

在chrome快捷方式,目标里如下设置

“C:\Program Files (x86)\Google\Chrome\Application\chrome.exe” –disable-web-security

发表在 前端 | 留下评论