zoukankan      html  css  js  c++  java
  • 几个文本处理工具的简单使用(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
    !!!
  • 相关阅读:
    896. Monotonic Array单调数组
    865. Smallest Subtree with all the Deepest Nodes 有最深节点的最小子树
    489. Robot Room Cleaner扫地机器人
    JavaFX
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
  • 原文地址:https://www.cnblogs.com/alongdidi/p/10408025.html
Copyright © 2011-2022 走看看