Linux文本处理相关

发布时间 2023-03-24 16:31:22作者: 秋来叶黄

awk

获取第一行内容

内容如下

$ lscpu
Architecture:            x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Address sizes:         39 bits physical, 48 bits virtual
  Byte Order:            Little Endian
CPU(s):                  8
  On-line CPU(s) list:   0-7
Vendor ID:               GenuineIntel
  Model name:            11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
    CPU family:          6
    Model:               140
    Thread(s) per core:  2
    Core(s) per socket:  4
    Socket(s):           1
    Stepping:            1
    CPU(s) scaling MHz:  59%
    CPU max MHz:         4200.0000
    CPU min MHz:         400.0000
    BogoMIPS:            4838.40

想获取第一行cpu架构,命令如下

$ lscpu|awk 'NR==1{print $0}'
Architecture:                    x86_64

NR是用来匹配第几行内容,NR==1表示第一行,print \$0是把整行输出。默认awk是空格分隔,所以如果是print \$1,就输出Architecture,如果是\$2就输出x86_64,如下

$ lscpu|awk 'NR==1{print $2}'
x86_64

获取倒数第几列

NF表示一共多少列,awk '{print $(NF-1)}'表示打印第NF-1列,也就是倒数第二列,因为NF是最后一列

增加判断条件

awk中可以增加一些条件语句,比如awk '{i++; if(i<5){print}}',表示一行行打印,只打印前5行

sed

sed替换分隔符有斜杠(/),冒号(:)和井号(#)

批量替换文件中的字符

sed -i "s/oldString/newString/g"  `grep oldString -rl path`

注意后面grep语句不是用单引号括起来的

&

sed匹配替换中,&符号代表上面匹配到的内容,比如想在匹配到的一行末尾或者开头增加字符

sed/s/key.*$/& add/ test.cfg

匹配test.cfg中所有包含key的行,.*$表示匹配到最后,然后把这个内容替换成& add&表示前面匹配的内容,也就是前面匹配的内容加上空格和add,就是在末尾增加了内容 add

替换内容举例

sed -i '/virtual.*= 0;/s/= 0;/{printf("file[%s], function[%s], line[%d]\n", __FILE__, __FUNCTION__, __LINE__);}/g' Include/database/otlv4.h

批量替换Include/database/otlv4.h文件中的内容,先匹配virtual.*= 0;,再把匹配的内容进行替换,把= 0;替换成{printf("file[%s], function[%s], line[%d]\n", __FILE__, __FUNCTION__, __LINE__);}

\1

斜杠加数字,表示匹配的第几个子串

echo test 1 text | sed 's/test \([0-9]\)/\1/'
1 text

sed匹配了一个子串数字1,就把test 1替换成了匹配的子串数字1。如果有多个子串,可以用\1 \2 \3一次代替。

echo test 123 | sed 's/\([a-z]\+\) \([0-9]\+\)/\2 \1/'
123 test

上面匹配了两个子串,第一个是test,第二个是123,所以后面交换一下,变成了123 test。

多次匹配

sed中可以多次匹配替换,比如sed 's/\[//;s/\]//',把匹配内容中的[]两个中括号去掉,多次匹配语句用分号(;)隔开

批量修改文件名

https://stackoverflow.com/questions/602706/batch-renaming-files-with-bash

for i in ./*.pkg ; do mv "$i" "${i/-[0-9.]*.pkg/.pkg}" ; done
  • 遍历循环当前目录下的pkg文件 ./*.pkg

  • 把获取到的i移动为

  • 移动的内容是一个匹配替换表达式,把i中包含-,中间是数字加.的替换掉

举例:

for i in ./*.py; do mv "$i" "${i/.py/_test.py}"; done

把当前目录下的所有py文件名在末尾增加一个_test

grep

只输出匹配内容

有时候我们只想输出匹配内容,可以使用-o参数,grep -o "[0-9a-z]*"匹配由数字和小写字母组成的字符串,并且只输出这个字符串内容,不输出整行。