shell中sed的使用

这里记录一下sed的使用, 并不会总结得很全,只是一些常见使用方法。 推荐一篇很好的sed的总结性文章点击这里 (是英文的,可能需要翻墙)

sed的常用方法

1. 替换字符串

1. 例子1(简单替换)
echo 'caesar is king' | sed 's/caesar/pig/'       
# 输出结果: pig is king

这是最简单的使用方式,其中caesar作为被替换的字符串, pig作为替换字符串。

2. 例子2(全局替换)

sed是每一行,每一行的流式操作的。

echo -e 'caesar is king, caesar\ncaesar is a girl' | sed 's/caesar/pig/'       
# 输出结果: pig is king, caesar
#           pig is a girl

可以看到sed只是把每一行的第一个caesar替换了, 不会替换所有的caesar, 替换每一行的所有caesar,需要加g选项

echo -e 'caesar is king, caesar\ncaesar is a girl' | sed 's/caesar/pig/g'       
# 输出结果: pig is king, pig
#           pig is a girl

tip: echo-e选项是输出字符串会经过转义,\n表示到下一行(linux)

3. 例子3(正则替换)

当然这里字符串的替换是可以使用正则表达式的, 一个例子如下:

echo -e 'caesar is king\ncurrent' | sed 's/^c[a-z]*/pig/'       
# 输出结果: pig is king
#           pig

这里将以c开头的单词替换为pig

再来一个复杂的例子,比如用shell脚本进行代码的混淆时, 我想找到objective-c代码的方法,比如我的方法是这样的格式的

- (instancetype)mc_initWithTitle:(NSString *)title{
}

而我想要提取出mc_initWithTitle这个方法名;

echo -e '- (void)mc_initWebView:(Nstring)3\n+ (void)mc_init;' | sed -r 's/^[-+] \(.*\)(mc_[0-9a-zA-Z_]*)([\;\:].*)?/\1/'     
# 输出结果: mc_initWebView
#           mc_init

这里-r选项是--regexp-extended,也就是正则扩展的意思, 不然sed的正则是不会识别()+这些符号的,这里一步步解释:
1:^[+-]代表以+或者-号开头;
2:空格就原样填写就行;
3:\(.*\)表示匹配任何单词加圆括号的东西,如(void), (unsigned);
4:(mc_[0-9a-zA-Z_]*)就是匹配方法名了;
5:([\;\:].*)?表示各种方法后的符号, 有: 有; 也可以什么都没有;
6:\1表示将之前匹配项1, 也就是(mc_[0-9a-zA-Z_]*)作为替换项进行替换
我们就得到了我们的方法名了;

4. 不使用/作为分隔符

也可以不使用/作为分隔符

sed 's_/usr/local/bin_/common/bin_' new
sed 's:/usr/local/bin:/common/bin:' new
sed 's|/usr/local/bin|/common/bin|' new

这里改用_ : |这三符号也行, 这样的话就可以不转义/就可以识别/

5. &的使用
echo "123 abc" | sed 's/[0-9]*/& &/'
# 输出:123 123 abc

&作为匹配项;

echo "123 abc" | sed 's/[^ ]*/(&)/g' 
# 输出:(123) (abc)

给单词加上括号

6. /1 /2匹配第一个、匹配第二个
echo "abc def" | sed -r 's/[a-z]+/000/1'
# 输出: 000 def
echo "abc def" | sed -r 's/[a-z]+/000/2'
# 输出: abc 000
echo "abc def ghi" | sed -r 's/[a-z]+/000/2g'
# 输出: abc 000 000

2g代表从第二个开始

2.其他操作

1. /p 打印

默认sed会打印所有行, 添加-n参数,sed之后打印改变行

echo -e "abc def ghi\n12" | sed -n 's/abc/&/p'
# 输出:abc def ghi

这是使用sed实现了grep的操作

2. /p 打印指定行
echo -e "line1\nline2\nline3" | sed -n '1p'
# 输出:line1
echo -e "line1\nline2\nline3" | sed -n '1,2p'
# 输出:line1
#      line2
echo -e "line1\nline2\nline3" | sed -n '$p'
# 输出:line3
# $p是打印最后一行
2. /I 忽略大小写
echo -e "abc\nABC" | sed -n '/abc/I p'
# 输出:abc
#      ABC
3. 组合操作
echo -e "abca" | sed -n 's/a/A/2pw /tmp/file' 
# 输出:abcA
#  并写入到/tmp/file   tip:w要放在最后
4. -e多命令组合
echo -e "abc" | sed -e 's/a/A/' -e 's/b/B/'
# 输出:ABc
5. 多文件
sed 's/^#.*//'  file1 file2 file3 | grep -v '^$' | wc -l
# 输出:输出多个文件中不是以#开头的行的行数

还有一个普遍使用方法是

sed 's/^#.*//'   `grep -lr  "pattern" dir`
# grep -lr dir输出文件夹dir下匹配pattern的文件

先写到这吧
todo: 写label g&G、 h&H、 x、 b、{}、

你可能感兴趣的:(shell中sed的使用)