Linux——管线命令pipe

79 篇文章 0 订阅
72 篇文章 1 订阅

注意:管线命令与连续下达命令是不一致的

管线命令只能处理由前一个指令传来的正确信息,也就是standard output信息,对于standard error并没有直接处理的能力。

每个管线的后面接的第一个数据一定是指令,该指令必须能够接受standard input的数据,这样的指令才可以是管线命令,例如less、more、head、tail都是可以接受standard input的管线命令,例如ls、cp、mv等不适管线命令,因为ls、cp、mv等并不会接受standard  input的数据。

      注意:(1)管线命令仅会处理standard  output,对于standard error output会予以忽略

                 (2)管线命令必须要能够接受 来自前一个指令的数据成为standard input继续处理才行

如果我们需要硬让standard error可以被管线命令所用,通过数据流重导向让2>&1加入指令中就可以让2>变成1>

1、摘取命令

<1>cut

    [dmtsai@study ~]$ cut -d'分隔字符' -f fields <==用于有特定分隔字符
    [dmtsai@study ~]$ cut -c 字符区间 <==用于排列整齐的讯息
        选项与参数:
            -d :后面接分隔字符。与 -f 一起使用;
            -f :依据 -d 的分隔字符将一段讯息分区成为数段,用 -f 取出第几段的意思;
            -c :以字符 (characters) 的单位取出固定字符区间;

    范例二:将 export 输出的讯息,取得第 12 字符以后的所有字符串
        [dmtsai@study ~]$ export
            declare -x HISTCONTROL="ignoredups"
            declare -x HISTSIZE="1000"
            declare -x HOME="/home/dmtsai"
            declare -x HOSTNAME="study.centos.vbird"
    # 注意看,每个数据都是排列整齐的输出!如果我们不想要『 declare -x 』时,就得这么做:
        [dmtsai@study ~]$ export | cut -c 12-
            HISTCONTROL="ignoredups"
            HISTSIZE="1000"
            HOME="/home/dmtsai"
            HOSTNAME="study.centos.vbird"
    # 还可以指定某个范围的值,例如第 12-20 的字符,就是 cut -c 12-20 等等!
<2>grep

cut指令是取出某部分我们想要的,而grep是分析一行信息

 

    [dmtsai@study ~]$ grep [-acinv] [--color=auto] '搜寻字符串' filename
       选项与参数:
           -a :将 binary 文件以 text 文件的方式搜寻数据
            -c :计算找到 '搜寻字符串' 的次数
            -i :忽略大小写的不同,所以大小写视为相同
            -n :顺便输出行号
            -v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!
            --color=auto :可以将找到的关键词部分加上颜色的显示喔!
    范例一:将 last 当中,有出现 root 的那一行就取出来;
        [dmtsai@study ~]$ last | grep 'root'
    范例二:与范例一相反,只要没有 root 的就取出!
        [dmtsai@study ~]$ last | grep -v 'root'
    范例三:在 last 的输出讯息中,只要有 root 就取出,并且仅取第一栏
        [dmtsai@study ~]$ last | grep 'root' |cut -d ' ' -f1
    # 在取出 root 之后,利用上个指令 cut 的处理,就能够仅取得第一栏啰!
    范例四:取出 /etc/man_db.conf 内含 MANPATH 的那几行
        [dmtsai@study ~]$ grep --color=auto 'MANPATH' /etc/man_db.conf
            MANPATH_MAP /usr/games /usr/share/man
            MANPATH_MAP /opt/bin /opt/man
            MANPATH_MAP /opt/sbin /opt/man
    # 神奇的是,如果加上 --color=auto 的选项,找到的关键词部分会用特殊颜色显示喔!

2、排序命令:sort、wc、uniq

<1>sort    ##按照一定方式将输出排序

 

    [dmtsai@study ~]$ sort [-fbMnrtuk] [file or stdin]
        选项与参数:
            -f :忽略大小写的差异,例如 A 与 a 视为编码相同;
            -b :忽略最前面的空格符部分;
            -M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
            -n :使用『纯数字』进行排序(默认是以文字型态来排序的);
            -r :反向排序;
            -u :就是 uniq ,相同的数据中,仅出现一行代表;
            -t :分隔符,预设是用 [tab] 键来分隔;
            -k :以那个区间 (field) 来进行排序的意思
    范例一:个人账号都记录在 /etc/passwd 下,请将账号进行排序。
        [dmtsai@study ~]$ cat /etc/passwd | sort
            abrt:x:173:173::/etc/abrt:/sbin/nologin
            adm:x:3:4:adm:/var/adm:/sbin/nologin
            alex:x:1001:1002::/home/alex:/bin/bash
    # 鸟哥省略很多的输出~由上面的数据看起来, sort 是预设『以第一个』数据来排序,而且默认是以『文字』型态来排序         的喔!所以由 a 开始排到最后啰!

<2>uniq    ##将重复的资料仅列出一个显示

    [dmtsai@study ~]$ uniq [-ic]
        选项与参数:
            -i :忽略大小写字符的不同;
            -c :进行计数
    范例一:使用 last 将账号列出,仅取出账号栏,进行排序后仅取出一位;
        [dmtsai@study ~]$ last | cut -d ' ' -f1 | sort | uniq
    范例二:承上题,如果我还想要知道每个人的登入总次数呢?
        [dmtsai@study ~]$ last | cut -d ' ' -f1 | sort | uniq -c
             1
             6 (unknown
             47 dmtsai
             4 reboot
             7 root
             1 wtmp
    # 从上面的结果可以发现 reboot 有 4 次, root 登入则有 7 次!大部分是以 dmtsai 来操作! wtmp 与第一行的空白都是             last 的默认字符,那两个可以忽略的!

<3>wc    ##对文件内容进行统计

    命令:$ wc  [-lwm]                                                                                                                                                                            选项与参数:
            -l :仅列出行;
            -w :仅列出多少字(英文单字);
            -m :多少字符;
    范例一:那个 /etc/man_db.conf 里面到底有多少相关字、行、字符数?
        [dmtsai@study ~]$ cat /etc/man_db.conf | wc 
             131 723 5171
    # 输出的三个数字中,分别代表: 『行、字数、字符数』
    范例二:我知道使用 last 可以输出登入者,但是 last 最后两行并非账号内容,那么请问,我该如何以一行指令串取得登入                    系统的总人次?
        [dmtsai@study ~]$ last | grep [a-zA-Z] | grep -v 'wtmp' | grep -v 'reboot' |  grep -v 'unknown' |wc -l 
    # 由于 last 会输出空白行, wtmp, unknown, reboot 等无关账号登入的信息,因此,我利用grep 取出非空白行,以及去除上         述关键词那几行,再计算行数,就能够了解啰!

3、双向重导向(同时将数据流传递给文件和屏幕)

 

[dmtsai@study ~]$  tee  [-a]  file
    选项与参数:
        -a :以累加 (append) 的方式,将数据加入 file 当中!

用途:使standard output 转存到文件中,并将文件内的数据显示到屏幕上,可以使我们分析同时记录数据,还可以作为处理数据的中间暂存盘使用。

4、字符转换命令:tr、col、join、paste、expand

<1>tr    删除或替换文字

 

    [dmtsai@study ~]$ tr [-ds] SET1 ...
        选项与参数:
            -d :删除讯息当中的 SET1 这个字符串;
            -s :取代掉重复的字符!
    范例一:将 last 输出的讯息中,所有的小写变成大写字符:
        [dmtsai@study ~]$ last | tr '[a-z]' '[A-Z]'
    # 事实上,没有加上单引号也是可以执行的,如:『 last | tr [a-z] [A-Z] 』
    范例二:将 /etc/passwd 输出的讯息中,将冒号 (:) 删除
        [dmtsai@study ~]$ cat /etc/passwd | tr -d ':'

<2>col    ##将tab键转换为对等的空格键

 

[dmtsai@study ~]$ col [-xb]
    选项与参数:
        -x :将 tab 键转换成对等的空格键
    范例一:利用 cat -A 显示出所有特殊按键,最后以 col 将 [tab] 转成空白
        [dmtsai@study ~]$ cat -A /etc/man_db.conf <==此时会看到很多 ^I 的符号,那就是 tab
        [dmtsai@study ~]$ cat /etc/man_db.conf | col -x | cat -A | more
    # 嘿嘿!如此一来, [tab] 按键会被取代成为空格键,输出就美观多了!

<3>join    ##处理两个文件之间的数据,对有相同数据的那一行,将他们加在一起

 

    [dmtsai@study ~]$  join  [-ti12]  file1  file2
        选项与参数:
            -t :join 默认以空格符分隔数据,并且比对『第一个字段』的数据,如果两个文件相同,则将两笔数据联成一行,且                      第一个字段放在第一个!
            -i :忽略大小写的差异;
            -1 :这个是数字的 1 ,代表『第一个文件要用那个字段来分析』的意思;
            -2 :代表『第二个文件要用那个字段来分析』的意思。
    范例二:我们知道 /etc/passwd 第四个字段是 GID , GID 记录在/etc/group 当中的第三个字段,请问如何两个文件整合?
        [root@study ~]# head -n 3 /etc/passwd /etc/group
            ==> /etc/passwd <==
            root:x:0:0:root:/root:/bin/bash
            bin:x:1:1:bin:/bin:/sbin/nologin
            daemon:x:2:2:daemon:/sbin:/sbin/nologin
            ==> /etc/group <==
            root:x:0:
            bin:x:1:
            daemon:x:2:
    # 从上面可以看到,确实有相同的部分喔!赶紧来整合一下!
        [root@study ~]# join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3
            0:root:x:0:root:/root:/bin/bash:root:x:
            1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:
            2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:
    # 同样的,相同的字段部分被移动到最前面了!所以第二个文件的内容就没再显示。
注意:在使用join之前,需要对所处理的问津先进行排序(sort)

<4>paste    ##paste直接将两行贴在一起,且中间以tab键隔开

 

    [dmtsai@study ~]$ paste [-d] file1 file2
        选项与参数:
            -d :后面可以接分隔字符。预设是以 [tab] 来分隔的!
            - :如果 file 部分写成 - ,表示来自 standard input 的资料的意思。

<5>expand    ##将tab键转换为空格键

 

    [dmtsai@study ~]$ expand [-t] file
        选项与参数:
            -t :后面可以接数字。一般来说,一个 tab 按键可以用 8 个空格键取代。我们也可以自行定义一个 [tab] 按键代表多少                    个字符呢!
    范例三:承上,我将 [tab] 按键设定成 6 个字符的话?
        [dmtsai@study ~]$ grep '^MANPATH' /etc/man_db.conf | head -n 3 | expand -t 6 - | cat -A
            MANPATH_MAP       /bin             /usr/share/man$
            MANPATH_MAP       /usr/bin             /usr/share/man$
            MANPATH_MAP       /sbin             /usr/share/man$    ##下划线表示空格

5、分区命令:split

    [dmtsai@study ~]$ split [-bl] file PREFIX
        选项与参数:
            -b :后面可接欲分区成的文件大小,可加单位,例如 b, k, m 等;
            -l :以行数来进行分区。
            PREFIX :代表前导符的意思,可作为分区文件的前导文字。
    范例一:我的 /etc/services 有六百多 K,若想要分成 300K 一个文件时?
        [dmtsai@study ~]$ cd /tmp; split -b 300k /etc/services services
        [dmtsai@study tmp]$ ll -k services*
            -rw-rw-r--. 1 dmtsai dmtsai 307200 Jul 9 22:52 servicesaa
            -rw-rw-r--. 1 dmtsai dmtsai 307200 Jul 9 22:52 servicesab
            -rw-rw-r--. 1 dmtsai dmtsai 55893 Jul 9 22:52 servicesac
    # 那个档名可以随意取,只要写上前导文字,小文件就会以xxxaa, xxxab, xxxac 等方式来建立小文件的!
    范例二:如何将上面的三个小文件合成一个文件,档名为 servicesback
        [dmtsai@study tmp]$ cat services* >> servicesback        # 数据流重导向

6、参数代换:xargs

        x指乘号,args指arguments(参数),即产生某个指令的参数,xargs可以读入stdin的数据,并且以空格或断行字符作为分别,将stdin的资料分隔称为arguments

 

    [dmtsai@study ~]$ xargs [-0epn] command
        选项与参数:
            -0 :如果输入的 stdin 含有特殊字符,例如 `, \, 空格键等等字符时,这个 -0 参数可以将他还原成一般字符。
            -e :这个是 EOF (end of file) 的意思。后面可以接一个字符串,当 xargs 分析到这个字符串时,就会停止继续工作!
            -p :在执行每个指令的 argument 时,都会询问使用者的意思;
            -n :后面接次数,每次 command 指令执行时,要使用几个参数的意思。当 xargs 后面没有接任何的指令时,默认是                      以 echo 来进行输出喔!
    范例一:将 /etc/passwd 内的第一栏取出,仅取三行,使用 id 这个指令将每个账号内容秀出来
        [dmtsai@study ~]$ id root
            uid=0(root) gid=0(root) groups=0(root) # 这个 id 指令可以查询用户的 UID/GID 等信息
        [dmtsai@study ~]$ id $(cut -d ':' -f 1 /etc/passwd | head -n 3)
    # 虽然使用 $(cmd) 可以预先取得参数,但可惜的是, id 这个指令『仅』能接受一个参数而已!
    # 所以上述的这个指令执行会出现错误!根本不会显示用户的 ID 啊!
        [dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | id
            uid=1000(dmtsai) gid=1000(dmtsai) groups=1000(dmtsai),10(wheel) # 我不是要查自己啊!
    # 因为 id 并不是管线命令,因此在上面这个指令执行后,前面的东西通通不见!只会执行 id!
        [dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs id
    # 依旧会出现错误!这是因为 xargs 一口气将全部的数据通通丢给 id 处理~但 id 就接受 1 个啊最多!
        [dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
            uid=0(root) gid=0(root) groups=0(root)
            uid=1(bin) gid=1(bin) groups=1(bin)
            uid=2(daemon) gid=2(daemon) groups=2(daemon)
    # 透过 -n 来处理,一次给予一个参数,因此上述的结果就 OK 正常的显示啰!
    范例二:同上,但是每次执行 id 时,都要询问使用者是否动作?
        [dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id
           id root ?...y
            uid=0(root) gid=0(root) groups=0(root)
            id bin ?...y
    #  -p 的选项可以让用户的使用过程中,被询问到每个指令是否执行!
    范例三:将所有的 /etc/passwd 内的账号都以 id 查阅,但查到 sync 就结束指令串
        [dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id
    # 仔细与上面的案例做比较。也同时注意,那个 -e'sync' 是连在一起的,中间没有空格键。上例中,第六个参数是 sync ,当下达 -e'sync' 后,则分析到 sync 这个字符串时,后面的其他 stdin 的内容就会被 xargs 舍弃掉了!
        使用 xargs 的原因是, 很多指令并不支持管线命令,因此我们可以透过 xargs 来提供该指令引用 standard input 之用!举例来说,我们使用如下的范例来说明:
    范例四:找出 /usr/sbin 底下具有特殊权限的档名,并使用 ls -l 列出详细属性
        [dmtsai@study ~]$ find /usr/sbin -perm /7000 | xargs ls -l
            -rwx--s--x. 1 root lock 11208 Jun 10 2014 /usr/sbin/lockdev
            -rwsr-xr-x. 1 root root 113400 Mar 6 12:17 /usr/sbin/mount.nfs
            -rwxr-sr-x. 1 root root 11208 Mar 6 11:05 /usr/sbin/netreport
    # 聪明的读者应该会想到使用『 ls -l $(find /usr/sbin -perm /7000) 』来处理这个范例!

7、减号- 的用途

某些文件名需要用到文件名来进行处理,该stdin与是stdout可以利用减号-来替代。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值