zoukankan      html  css  js  c++  java
  • Linux Shell编程 cut、print命令

    cut命令:查找符合条件的列

    cut  命令是在文件中提取符合条件的列,虽然 cut 命令用于提取符合条件的列,但是也要一行一行地进行数据提取。也就是说,先要读取文本的第一行数据,在此行中判断是否有符合条件的字段,然后再处理第二行数据。我们也可以把 cut 成为字段提取命令。命令格式如下:

    [root@localhost ~]# cut [选项] 文件名

    选项:

    • -f 列号:提取第几列;
    • -d 分隔符:按照指定分隔符分割列;
    • -c 字符范围:不依赖分隔符来区分列,而是通过字符范围(行首为 0)来进行字段提取。"n-"表示从第 n 个字符到行尾;"n-m"表示从第 n 个字符到第 m 个字符;"-m"表示从第 1 个字符到第 m 个字符;

    cut命令示例

    cut 命令的默认分隔符是制表符,也就是 Tab 键。我们先建立一个测试文件,然后看看 cut 命令的作用。

    [root@localhost ~]# vi student.txt
    ID Name gender Mark
    1 Liming M 86
    2 Sc M 90
    3 Gao M 83

    建立学员成绩表,注意这张表中所有的分隔符都是制表符,不能是空格,否则后面的实验会出现问题。 

    先看看 cut 命令该如何使用:

    [root@localhost ~]# cut -f 2 student.txt
    #提取第二列的内容
    Name
    Liming
    Sc
    Gao

    如果想要提取多列,将列号直接用","隔开,命令如下:

    [root@localhost ~]# cut -f 2,3 student.txt
    #提取第二列和第三列的内容
    Name gender
    Liming M
    Sc M
    Gao M

    cut 命令可以按照字符进行提取。需要注意的是,"8-"代表提取所有行从第 8 个字符到行尾,而"10-20"代表提取所有行的第 10~20 个字符,而"-8"代表提取所有行从行首到第 8 个字符,命令如下:

    [root@localhost ~]#cut-c 8- student.txt
    #提取取每行从第8个字符到行尾,好像很乱啊,那是因为每行的字符个数不相等
    gender Mark
    g M 86
    90
    83

    当然,cut 命令也可以手工指定分隔符。例如,我想看看当前 Linux 服务器中有哪些用户、用户的 UID 时,就可以这样操作:

    [root@localhost ~]# cut -d ":" -f 1,3 /etc/passwd
    #以":"作为分隔符,提取/etc/passwd文件的第一列和第三列
    root:0
    bin:1
    daemon:2
    adm:3
    lp:4

    cut 命令很方便,不过最主要的问题是对空格识别得不好,很多命令的输出格式中都不是制表符,而是空格符,比如:

    [root@localhost ~]# df
    #统计分区使用状况
    文件系统 1K-块 已用 可用 已用% 挂载点
    /dev/sda3 19923216 1848936 17062212 10% /
    tmpfs 312672 0 312672 0% /dev/shm
    /dev/sda1 198337 26359 161738 15% /boot
    /dev/srO 3626176 3626176 0 100% /mnt/cdrom

    如果想用 cut 命令截取第一列和第三列,就会出现这样的情况:

    [root@localhost ~]# df -h|cut -d""-f 1,3
    文件系统
    /dev/sda3
    tmpfs
    /dev/sda1
    /dev/sr0

    因为 df 命令输出的分隔符不是制表符,而是多个空格符,所以 cut 命令会将每个空格符当作一个分隔符,而这样数,第三列刚好也是空格,所以输出才会是上面这种情况。

    总之,cut 命令不能很好地识别空格符。如果想要以空格符作为分隔符,建议使用 awk 命令。

    printf命令:格式化输出

     print 会在每个输出之后自动加入一个换行符;而 printf 是标准格式输出命令,并不会自动加入换行符,如果需要换行,则需要手工加入换行符。在 awk 中可以识别 print 输出动作和 printf 输出动作,但是在 Bash 中只能识别标准格式化输出命令 printf。printf 命令格式如下:

    [root@localhost ~]# printf '输出类型输出格式' 输出内容

    输出类型:

    • %ns:输出字符串。n 是数字,指输出几个字符;
    • %ni:输出整数。n 是数字,指输出几个数字‘’
    • %m.nf: 输出浮点数。m 和 n 是数字,指输出的整数位数和小数位数。如 %8.2f 代表共输出 8 位数,其中 2 位是小数,6 位是整数;

    输出格式:

    • a: 输出警告声音;
    • :输出退格键,也就是 Backspaced 键;
    • f:清除屏幕;
    • :换行;
    • :回车,也就是 Enter 键;
    • :水平输出退格键,也就是 Tab 键;
    • v:垂直输出退格键,也就是 Tab 键;

    printf命令示例

    创建 student.txt 文件。文件内容如下:

    [root@localhost ~]# vi student.txt
    ID Name PHP Linux MySQL Average
    1 Liming 82 95 86 87.66
    2 Sc 74 96 87 85.66
    3 Gao 99 83 93 91.66

    使用 printf 命令输出这个文件的内容,如下:

    [root@localhost ~]# printf '%s' $(cat student.txt)
    IDNamegenderPHPUnuxMySQl_Average1LjmingM82 958687.662ScM74968785.663GaoM998393 91.66

    printf 命令如果不指定输出格式,则会把所有输出内容连在一起输出。其实文本的输出本身就是这样的,cat 等文本输出命令之所以可以按照格式漂亮地输出,那是因为 cat 命令已经设定了输出格式。

    那么,为了用 printf 输出合理的格式,应该这样做:

    [root@localhost ~]# printf '%s	 %s	 %s	 %s	 %s	 %s	
    ' $(cat student.txt)
    #注意:在printf命令的单引号中只能识别格式输出符号,而手工输入的空格是无效的
    ID Name PHP Linux MySQL Average
    1 Liming 82 95 86 87.66
    2 Sc 74 96 87 85.66
    3 Gao 99 83 93 91.66

    在 printf 命令的单引号中输入的任何空格都不会反映到格式输出中,只有格式输出符号才能影响 printf 命令的输出结果。
    因为我们的文档有6列,所以使用 6 个"%s"代表这 6 列字符串,每个字符串之间用" "分隔;最后还要加入" ",使得每行输出都换行,否则这些数据还是会连成一行的。
    如果不想把成绩当成字符串输出,而是按照整型和浮点型输出,则要这样做:

    [root@localhost ~]# printf '%i	 %s	 %i	 %i	 %i	 %8.2f	
    '  $(cat student.txt | grep -v Name)
    1 Liming 82 95 86 87.66
    2 Sc 74 96 87 85.66
    3 Gao 99 83 93 91.66

    先解释"cat student.txt|grep -v Name"这条命令。这条命令会把第一行标题取消,剩余的内容才用 printf 格式化输出。在剩余的内容中,第 1、3、4、5 列为整型,所以用"%i"输出;而第 2 列是字符串,所以用"%s"输出;而第 6 列是小数,所以用"%8.2f"输出。"%8.2f"代表可以输出 8 位数,其中有 2 位是小数,有 6 位是整数。

     

  • 相关阅读:
    108. Convert Sorted Array to Binary Search Tree
    How to check if one path is a child of another path?
    Why there is two completely different version of Reverse for List and IEnumerable?
    在Jenkins中集成Sonarqube
    如何查看sonarqube的版本 how to check the version of sonarqube
    Queue
    BFS广度优先 vs DFS深度优先 for Binary Tree
    Depth-first search and Breadth-first search 深度优先搜索和广度优先搜索
    102. Binary Tree Level Order Traversal 广度优先遍历
    How do I check if a type is a subtype OR the type of an object?
  • 原文地址:https://www.cnblogs.com/lizhouwei/p/10029056.html
Copyright © 2011-2022 走看看