• shell脚本常用命令(三)


    shell脚本常用命令(三)

    cut按列切分文件

    cut命令可以按列,而不是按行来切分文件。该命令可用于处理使用固定宽度字段的文件、CSV文件或是由空格分隔的文件(例如标准日志文件)。

    • -f选项可以指定要提取的字段。
    • -d选项能够设置分隔符。
    • --complement选项可以显示出没有被-f指定的那些字段。
    • --output-delimiter选项可以指定输出分隔符。

    上述部分选项实例:

    [root@localhost shell_learning]$ cat output.txt
    123 456 789 999 456 789
    123 456 789 999 456 789
    123 456 789 999 456 789
    
    [root@localhost shell_learning]$ cut -d ' ' -f2 output.txt
    456
    456
    456
    
    [root@localhost shell_learning]$ cut -d ' ' -f2,3 output.txt #2 3列
    456 789
    456 789
    456 789
    
    [root@localhost shell_learning]$ cut -d ' ' -f1-3 output.txt #1~3列
    123 456 789
    123 456 789
    123 456 789
    
    [root@localhost shell_learning]$ cut -d ' ' -f3- output.txt # 3列及之后
    789 999 456 789
    789 999 456 789
    789 999 456 789
    
    [root@localhost shell_learning]$ cut -d ' ' -f-3 output.txt # 3列及之前
    123 456 789
    123 456 789
    123 456 789
    [root@localhost shell_learning]$ cut -d ' ' -f-3 --output-delimiter "," output.txt # 3列及之前,每列用","分割并输出
    123,456,789
    123,456,789
    123,456,789
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    awk 进行高级文本处理

    awk脚本的结构如下:

    awk 'BEGIN{ print "start" } pattern { commands } END{ print "end" }' file
    
    • 1

    下面的命令会输出文件行数:

    awk 'BEGIN { i=0 } { i++ } END { print i}' filename
    
    • 1

    工作原理

    awk命令的工作方式如下。

    • (1) 首先执行BEGIN { commands } 语句块中的语句。
    • (2) 接着从文件或stdin中读取一行,如果能够匹配pattern, 则执行随后的commands语句块。重复这个过程,直到文件全部被读取完毕。
    • (3) 当读至输入流末尾时,执行END { commands } 语句块。

    具体过程:

    • BEGIN语句块在awk开始从输入流中读取行之前被执行。这是一个可选的语句块,诸如变量初始化、打印输出表格的表头等语句通常都可以放在BEGIN语句块中。
    • END语句块和BEGIN语句块类似。它在awk读取完输入流中所有的行之后被执行。像打印所有行的分析结果这种常见任务都是在END语句块中实现的。
    • 最重要的部分就是和pattern关联的语句块。这个语句块同样是可选的。如果不提供,则默认执行{ print },即打印所读取到的每一行。 awk对于读取到的每一行都会执行该语句块。这就像一个用来读取行的while循环,在循环体中提供了相应的语句。
    • 每读取一行, awk就会检查该行是否匹配指定的模式。模式本身可以是正则表达式、条件语句以及行范围等。如果当前行匹配该模式,则执行{ }中的语句。

    模式是可选的。如果没有提供模式,那么awk就认为所有的行都是匹配的:
    当使用不带参数的print时,它会打印出当前行,如下所示:

    [root@localhost shell_learning]$ echo -e "line1\nline2" | awk 'BEGIN { print "Start" } { print } END { print "End" } '
    Start
    line1
    line2
    End
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    echo命令向标准输出写入一行,因此awk{ } 语句块中的语句只被执行一次。如果awk的输入中包含多行,那么 { } 语句块中的语句也就会被执行相应的次数。如下例所示:

    [root@localhost shell_learning]$ echo -e "123 " | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1 "-" var2 "-" var3 ; }'
    v1-v2-v3
    [root@localhost shell_learning]$ echo -e "123\n456\n789 " | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1 "-" var2 "-" var3 ; }'
    v1-v2-v3
    v1-v2-v3
    v1-v2-v3
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    特殊变量

    以下是awk可以使用的一些特殊变量。

    • NR:表示记录编号,当awk将行作为记录时,该变量相当于当前行号。
    • NF:表示字段数量,在处理当前记录时,相当于字段数量。默认的字段分隔符是空格。
    • $0:该变量包含当前记录的文本内容。
    • $1:该变量包含第一个字段的文本内容。
    • $2:该变量包含第二个字段的文本内容。

    实例如下:

    [root@localhost shell_learning]$ echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7\nline4 f8 f9 f10" |                                                                                           awk '{
          print "Line no:"NR",No of fields:"NF, "$0="$0,
         "$1="$1,"$2="$2,"$3="$3
    }'
    Line no:1,No of fields:3 $0=line1 f2 f3 $1=line1 $2=f2 $3=f3
    Line no:2,No of fields:3 $0=line2 f4 f5 $1=line2 $2=f4 $3=f5
    Line no:3,No of fields:3 $0=line3 f6 f7 $1=line3 $2=f6 $3=f7
    Line no:4,No of fields:4 $0=line4 f8 f9 f10 $1=line4 $2=f8 $3=f9
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    下面的命令会打印出每一行的第二和第三个字段:

    $awk '{ print $3, $2 }' file
    
    • 1

    我们可以使用NR统计文件的行数:

    $ awk 'END{ print NR }' file
    
    • 1

    你可以将每一行中第一个字段的值按照下面的方法累加:

    [root@localhost shell_learning]$ seq 5 | awk 'BEGIN { sum=0; print "Summation:" }{ print $1"+"; sum+=$1 } END { print "=="; print sum }'
    Summation:
    1+
    2+
    3+
    4+
    5+
    ==
    15
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    将外部变量值传递给awk

    • -v选项,我们可以将外部值(并非来自stdin)传递给awk。

    实例:

    [root@localhost shell_learning]$ var=100000
    [root@localhost shell_learning]$ echo | awk -v variable=$var '{ print variable }'
    100000
    
    • 1
    • 2
    • 3

    还有另一种灵活的方法可以将多个外部变量传递给awk。例如:

    [root@localhost shell_learning]$ var1="Variable1" ; var2="Variable2"
    [root@localhost shell_learning]$ echo | awk '{ print v1,v2 }' v1=$var1 v2=$var2
    Variable1 Variable2
    
    
    • 1
    • 2
    • 3
    • 4

    用getline读取行

    实例:

    [root@localhost shell_learning]$ seq 5 | awk 'BEGIN { getline; print "Read ahead first line", $0 }{ print $0 }'
    Read ahead first line 1
    2
    3
    4
    5
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用过滤模式对awk处理的行进行过滤

    $ awk 'NR < 5' # 行号小于5的行
    $ awk 'NR==1,NR==4' # 行号在1到5之间的行
    $ awk '/linux/' # 包含模式为linux的行(可以用正则表达式来指定模式)
    $ awk '!/linux/' # 不包含模式为linux的行
    
    • 1
    • 2
    • 3
    • 4

    设置字段分隔符

    -F选项默认的字段分隔符是空格。我们也可以用选项指定不同的分隔符。

    $ awk -F: '{ print $NF }' /etc/passwd
    
    • 1

    或者

    awk 'BEGIN { FS=":" } { print $NF }' /etc/passwd
    
    • 1

    BEGIN语句块中可以将字段分隔符设置为:

    实例:

    [root@localhost shell_learning]$ cat output.txt
    123:456:789:999:456:789
    123:456:789:999:456:789
    123:456:789:999:456:789
    var1="123"
    var2="789"
    [root@localhost shell_learning]$ awk 'BEGIN {FS=":"} { "grep 123 ./output.txt " | getline; print $1,$6  } '
    
    123 789
    
    123 789
    
    123 789
    
    var1="123"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    awk内建的字符串处理函数

    • length(string):返回字符串string的长度。
    • index(string, search_string): 返回search_string在字符串string中出现的位置。
    • split(string, array, delimiter):以delimiter作为分隔符, 分割字符串string,将生成的字符串存入数组array。
    • substr(string, start-position, end-position) : 返 回 字 符 串 string 中以start-positionend-position作为起止位置的子串。
    • sub(regex, replacement_str, string):将正则表达式regex匹配到的第一处内容替换成replacment_str
    • gsub(regex, replacement_str, string):和sub()类似。不过该函数会替换正则表达式regex匹配到的所有内容。
    • match(regex, string):检查正则表达式regex是否能够在字符串string中找到匹配。如果能够找到,返回非0值;否则, 返回0
      match()有两个相关的特殊变量,
      分别是RSTARTRLENGTH。变量RSTART包含了匹配内容的起始位置,而变量RLENGTH包含了匹配内容的长度。

    循环

    实例1:
    终端计数显示:

    for count in `seq 0 40`
    do
    	tput rc
    	tput ed
    	echo -n $count
    	sleep 1
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    面向列表的for循环

    for var in list;
    do
    	commands; #使用变量$var
    done
    
    • 1
    • 2
    • 3
    • 4

    list可以是一个字符串,也可以是一个值序列。

    迭代指定范围的数字(for)

    for((i=0;i<10;i++))
    {
    	commands; #使用变量$i
    }
    
    • 1
    • 2
    • 3
    • 4

    循环到条件满足为止(while)

    while condition
    do
    	commands;
    done
    
    • 1
    • 2
    • 3
    • 4

    until循环

    Bash中还可以使用一个特殊的循环until。它会一直循环,直到给定的条件为真。例如:

    x=0;
    until [ $x -eq 9 ]; #条件是[ $x -eq 9 ]
    do
    	let x++; echo $x;
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    c#装饰器模式详解
    0 基础 Java 自学之路(4)
    基于SSM的动漫商城管理系统
    bean的生命周期
    最长回文子序列 递归与动态规划
    算法笔记--最大连续1的个数Ⅲ
    【一起撸个DL框架】5 实现:自适应线性单元
    Mac上在vm虚拟机上搭建Hadoop集群并安装zookeeper hive hbase
    HTTP四大参数类型及请求参数的方式和如何接收
    XP-CLR分析学习笔记
  • 原文地址:https://blog.csdn.net/qq_40700822/article/details/125218506