• 几个文本处理工具的简单使用(wc,cut,sort,uniq,diff和patch)


    wc

    wc命令用于报告文本文件的一些统计计数,例如行数、单词数、字节数等。

    语法如下。

    wc [OPTION]... [FILE]...
    wc [OPTION]... --files0-from=F

    --files0-from=F:这个选项几乎没见过有人使用,我也看不懂,因此就忽略掉了。

    默认情况下显示3个计数,从左往右分别是行数、单词数和字节数。

    [root@C7 ~]# wc /etc/passwd
      51   94 2599 /etc/passwd

    如果被统计的文件数大于1,那么还会显示一行总计。

    [root@C7 ~]# wc /etc/passwd /etc/init.d/functions 
       51    94  2599 /etc/passwd
      707  2364 18104 /etc/init.d/functions
      758  2458 20703 total

    可以通过选项控制,单独显示这3个计数。

    -l, --lines:显示行数。

    [root@C7 ~]# wc -l /etc/passwd
    51 /etc/passwd

    -w, --words:显示单词数。

    [root@C7 ~]# wc -w /etc/passwd
    94 /etc/passwd

    -c, --bytes:显示字节数。

    [root@C7 ~]# wc -c /etc/passwd
    2599 /etc/passwd

    还可以显示一些另外的计数。

    -m, --chars:显示字符数。

    [root@C7 ~]# wc -m /etc/passwd
    2599 /etc/passwd

    -L, --max-line-length:显示文件中最长的行的长度。

    [root@C7 ~]# wc -L /etc/passwd
    99 /etc/passwd

    cut

    从一个文本文件中,截取我们所需要的部分进行显示,一般是用于有固定的分隔符的文本文件,例如/etc/passwd这种以“:”作为分隔符的文件。

    cut的默认分隔符是TAB。

    语法如下。

    cut OPTION... [FILE]...

    我们创建一个测试文件cut.txt,第一行以TAB分隔,第二行以一个空格分隔,第三行分别以一个空格、两个空格和三个空格分隔。

    [root@C7 ~]# cat -A cut.txt
    a^Ilong^Idi^Idi$
    a long di di$
    a long  di   di$

    在“cat -A”的输出中,“^I”表示TAB,“$”表示换行符。

    -f, --fields=LIST:指定要截取每一行中第几个字段的数据。

    这里的LIST,可以是单独的某个字段,也可以是连续的字段范围,也可以是离散的字段,如下所示。

    # cut -f 2 FILE
    # cut -f 2,3,4 FILE
    # cut -f 2-5 FILE
    # cut -f 1,2-3,5 FILE
    # cut -f 2- FILE:从第2个字段到行尾。
    # cut -f -2 FILE:从行首到第2个字段。

    LIST也可用于后面的-b和-c选项。

    然后我们尝试对cut.txt取第二个字段。

    [root@C7 ~]# cut -f 2 cut.txt 
    long
    a long di di
    a long  di   di

    我们发现,第一行以TAB为分隔符的行取出的字段是正确的,另外2个字段是整行都取出来了。

    这是因为默认情况下不包含分隔符的行会被整行打印,如果想避免这种情况可以使用-s选项。

    -s, --only-delimited:只打印那些包含分隔符的行。

    [root@C7 ~]# cut -sf 2 cut.txt 
    long

    这里有一点需要注意,使用短选项的时候,-f后面必须跟着数字,如果跟其他选项就会报错。

    [root@C7 ~]# cut -fs 2 cut.txt 
    cut: invalid byte, character or field list

    -d, --delimiter=DELIM:指定分隔符,而不使用默认的TAB,这个选项很有用,许多文件的默认分隔符都不是TAB。

    [root@C7 ~]# head -n 3 /etc/passwd | cut -d : -f 7
    /bin/bash
    /sbin/nologin
    /sbin/nologin

    -b, --bytes=LIST:只取多少个字节数的数据。

    -c, --characters=LIST:只取多少个字符数的数据。

    当取的数据是数字和字母的时候,这两个选项的结果一般是相同的。

    [root@C7 ~]# echo "alongdidi" | cut -b 1-4
    alon
    [root@C7 ~]# echo "alongdidi" | cut -c 1-4
    alon

    --output-delimiter=STRING:设置输出时候的分隔符,默认是采用和输入文件相同的分隔符。

    [root@C7 ~]# grep -E "^(root|zwl)" /etc/passwd | cut -d : -f 1,7
    root:/bin/bash
    zwl:/bin/bash
    [root@C7 ~]# grep -E "^(root|zwl)" /etc/passwd | cut -d : -f 1,7 --output-delimiter "'s shell ="
    root's shell =/bin/bash
    zwl's shell =/bin/bash

    sort

    sort用于将文件排序后显示。

    语法如下。

    sort [OPTION]... [FILE]...
    sort [OPTION]... --files0-from=F

    sort的排序可以针对多个文件,一起排序后显示。

    [root@C7 ~]# cat sort1.txt 
    aaa
    ccc
    bbb
    [root@C7 ~]# cat sort2.txt 
    eee
    fff
    ddd
    [root@C7 ~]# sort sort1.txt 
    aaa
    bbb
    ccc
    [root@C7 ~]# sort sort1.txt sort2.txt 
    aaa
    bbb
    ccc
    ddd
    eee
    fff

    sort的默认排序方式,是先比较第一个字符,如果一样,则再比较第二个字符。以此类推。

    数字的排序方式是0~9,字母的排序方式是a~z。

    如果字母相同只是大小写不同的话,那么小写排在大写的前面,例如a排在A的前面。

    [root@C7 ~]# cat sort.txt
    aaa
    DDD
    fff
    AAA
    bbb
    BBB
    eee
    CCC
    999
    876
    333
    [root@C7 ~]# sort sort.txt
    333
    876
    999
    aaa
    AAA
    bbb
    BBB
    CCC
    DDD
    eee
    fff

    -r, --reverse:sort默认是有小到大排序,该选项则用于反向排序。

    [root@C7 ~]# sort sort.txt
    111
    222
    555
    888
    [root@C7 ~]# sort -r sort.txt
    888
    555
    222
    111

    -n, --numeric-sort:基于数值排序。由于sort默认的排序机制导致sort没办法将数字按照数值大小准确排序,需要加上该选项方可实现。

    [root@C7 ~]# sort sort.txt
    1790
    180
    19
    [root@C7 ~]# sort -n sort.txt
    19
    180
    1790

    -t, --field-separator=SEP:指定字段分隔符。

    -k, --key=KEYDEF:指定排序依据的字段。

    二者结合可以使得sort在排序某个文件的时候根据每行固定的字段来排序。例如根据UID排序/etc/passwd。

    [root@C7 ~]# head -n 5 /etc/passwd | sort -t : -k 3 -n
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    -f, --ignore-case:忽略大小写排序,原理是sort内部会将小写字母转换成大写字母来排序。

    -u, --unique:使得重复的行只出现一次,结合-f选项的话,只会保留一种大写/小写的情况。

    [root@C7 ~]# sort sort.txt
    aaa
    aaa
    AAA
    bbb
    bbb
    BBB
    ddd
    jjj
    ooo
    [root@C7 ~]# sort -uf sort.txt
    aaa
    BBB
    ddd
    jjj
    ooo

    uniq

    uniq用于报告或者忽略掉重复的行。但是只会将相邻的重复行移除掉,而不是将整个文本中重复的行移除掉。

    [root@C7 ~]# cut -d : -f 7 /etc/passwd
    /bin/bash
    /sbin/nologin
    -- 多个重复 --
    /sbin/nologin
    /bin/sync
    /sbin/shutdown
    /sbin/halt
    /sbin/nologin
    -- 多个重复 --
    /sbin/nologin
    /bin/bash
    -- 多个重复 --
    /bin/bash
    /sbin/nologin
    [root@C7 ~]# cut -d : -f 7 /etc/passwd | uniq
    /bin/bash
    /sbin/nologin
    /bin/sync
    /sbin/shutdown
    /sbin/halt
    /sbin/nologin
    /bin/bash
    /sbin/nologin

    这可能不是我们所要的结果,一般我们会先使用sort排序一下,再使用uniq移除相邻的重复行。这样子就可以实现删除文本中重复的行的功能。

    [root@C7 ~]# cut -d : -f 7 /etc/passwd | sort | uniq
    /bin/bash
    /bin/sync
    /sbin/halt
    /sbin/nologin
    /sbin/shutdown

    -c, --count:uniq区别于“sort -u”的主要一点在于它还可以统计重复的行所出现的次数。

    [root@C7 ~]# cut -d : -f 7 /etc/passwd | sort | uniq -c
          9 /bin/bash
          1 /bin/sync
          1 /sbin/halt
         39 /sbin/nologin
          1 /sbin/shutdown

    -d, --repeated:只显示有重复的行。

    [root@C7 ~]# cut -d : -f 7 /etc/passwd | sort | uniq -cd
          9 /bin/bash
         39 /sbin/nologin

    -u, --unique:也可以只打印不重复的行。

    [root@C7 ~]# cut -d : -f 7 /etc/passwd | sort | uniq -u
    /bin/sync
    /sbin/halt
    /sbin/shutdown

    diff和patch

    diff用于对比两个文本文件的区别,对比的结果本质上是一个补丁文件,可以让patch用来对文件打补丁。

    首先我们先看两个文本文件的内容。

    [root@C7 ~]# cat -n old_file.txt 
         1    today
         2    is
         3    thursday
         4    !!!
    [root@C7 ~]# cat -n new_file.txt 
         1    today
         2    is
         3    not
         4    thursday
         5    !?!?

    接下来看diff的默认比对结果。

    [root@C7 ~]# diff old_file.txt new_file.txt 
    2a3
    > not
    4c5
    < !!!
    ---
    > !?!?

    这个结果其实就是描述了被对比的两个文件之间的区别,只不过这个描述我们人类比较难以理解,将这个描述重定向至文本文件,那么该文件就成为一个补丁文件了。

    [root@C7 ~]# diff old_file.txt new_file.txt > patch.txt

    当我们拥有old_file.txt和补丁文件patch.txt的时候,我们就可以通过patch命令打补丁将old_file.txt变成(“升级”)new_file.txt。

    [root@C7 ~]# patch -i patch.txt old_file.txt 
    patching file old_file.txt
    [root@C7 ~]# cat old_file.txt 
    today
    is
    not
    thursday
    !?!?

    如果想使得old_file.txt变回打补丁前的样子,可以在使用patch命令的时候,加上-R选项,打反向补丁。

    [root@C7 ~]# patch -Ri patch.txt old_file.txt 
    patching file old_file.txt
    [root@C7 ~]# cat old_file.txt 
    today
    is
    thursday
    !!!
  • 相关阅读:
    Java Synchronized的用法
    静态方法中不能new内部类的实体对象
    android ViewGroup事件分发机制
    安卓设备通过USB接口读取UVC摄像头权限问题
    android View事件分发机制结论
    函数指针与指针函数以及typedef
    GeoHash
    快速排序,C语言实现
    字符串的几个算法
    ANSI C与GNU C
  • 原文地址:https://www.cnblogs.com/alongdidi/p/10408025.html
Copyright © 2020-2023  润新知