Linux下的文本处理

linux经常用到文本处理,比如sed,awk,grep,而这些又离不开正则表达式。每个都能写一个长篇博客,并且还不一定能写完。

1. sed

sed一般用于单行文本操作,但是这里我只讲多行操作。

给同学改一个网站,把二十多个的html中的公共部分提取出来,做成一个sidebar.html,然后把那二十多个html中相同的代码块替换成include sidebar.html。

sed多行匹配是这样的
sed '/<script>/,/<\/script/p' file
匹配的文本特征为:开始行包含<script>,结束行包含</script>的代码块。匹配是非贪婪的,即找到第一个满足条件的就停止。比如如下golang代码段

package main
import "fmt"
func sum(a []int, c chan int) {
        sum := 0
        for _, v := range a {
                sum += v
        }
        c <- sum
}
func main() {
        a := []int{7, 2, 8, -9, 4, 0}

        c := make(chan int)
        go sum(a[:len(a)/2], c)
        go sum(a[len(a)/2:], c)
        x, y := <-c, <-c
        fmt.Println(x, y, x+y)
}

sed -n '/func/,/}/p' channels.go匹配的结果如下

func sum(a []int, c chan int) {
        sum := 0
        for _, v := range a {
                sum += v
        }
func main() {
        a := []int{7, 2, 8, -9, 4, 0}

sed -n '/func/,/^}/p' channels.go的匹配结果如下

func sum(a []int, c chan int) {
    sum := 0
    for _, v := range a {
            sum += v
    }
    c <- sum
}
func main() {
    a := []int{7, 2, 8, -9, 4, 0}

    c := make(chan int)
    go sum(a[:len(a)/2], c)
    go sum(a[len(a)/2:], c)
    x, y := <-c, <-c
    fmt.Println(x, y, x+y)
}

另外还可以指定偏移行数来确定代码段,比如下面的命令可以输出文件夹下所有html文件中,从含有<div class="balabala">的行开始,并且向下6行的代码。
find . -name "*.html" | xargs sed -n '/<div class="balabala">/,+6'p
于是,同学的问题也解决了。

2. awk

以前不知道有pkill,于是我kill到所有包含chrome的进程,都是这么搞的。。
ps aux | grep chromium | awk '{print $2}' | sort -nr | xargs kill -9
awk可以按列处理文本,因此提取中ps的输出的第二列,刚好是pid。

sort -nr使其从大到小排列,因为较大的进程号往往是较小的进程的子进程。
如果先kill小的进程,也就是父进程,那么父进程的子进程也被kill掉了。后面的kill可能会出错,提示找不到进程。如果从子进程开始kill,就不会出现问题。

为了杀个进程也是蛮拼的。。

3. grep

grep一个淫荡的技巧是不输出grep所在的那个进程。
ps aux | grep [c]hroium
原理就是正则表达式”[c]hroium”的语义是字符串”[c]hroium”,但是从形式上二者已经不一样了。
于是grep拿正则表达式”[c]hroium”来匹配字符串”[c]hroium”,二者很明显不匹配。

还有一个选项-o,是只输出匹配的文本,加上正则表达式的断言,可以很精确的提取出所需的文本。
写过一个校园网命令行登录脚本,提取url参数的脚本如下。

echo "<script>top.self.location.href='http://192.168.50.3:8080/eportal/index.jsp?wlanuserip=3d45d9f205c3becb730fdd2b3b232b75&wlanacname=dfa22de185f6a920f90e17e3559e0244&ssid=&nasip=2e9fe26292ae028fc7e9f7d72d6b9a88&mac=ed4a68163130d2ec94707fe1ecab3fb0&t=wireless-v2&url=709db9dc9ce334aad9f3cf534a58c238a63df9f3a78ce15e'</script>" | grep -o -P "(?<=\?).*(?='</)"

输出结果如下

wlanuserip=3d45d9f205c3becb730fdd2b3b232b75&wlanacname=dfa22de185f6a920f90e17e3559e0244&ssid=&nasip=2e9fe26292ae028fc7e9f7d72d6b9a88&mac=ed4a68163130d2ec94707fe1ecab3fb0&t=wireless-v2&url=709db9dc9ce334aad9f3cf534a58c238a63df9f3a78ce15e
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值