• 【Linux】- 对find,xargs,grep和管道的一些理解


    问题

    相信大家都知道在目录中搜索含有固定字符串文件的命令:

    find . -name '*.py' |xargs grep test

    刚开始的时候,我不熟悉xargs命令,所以直接使用的命令是:

    find . -name '*.py' |grep test

    结果并不是自己所期望的。此命令只是找出文件名中包含"test"的文件。

    本文旨在揭示xargs究竟做了什么,使得结果不一样。

    参数与标准输入

    这两个词在Linux命令中是很常见的。但是参数和标准输入其实是有区别的。我们日常使用的很多命令,例如:ls -lah .中。l、 a、 h 、.都是命令ls的参数。至于标准输入,可以说它是某种流数据。而通常来讲标准输入的流数据来源就是我们的终端输入。在Linux命令中,有些命令可以接收标准输入,有些是不能的。像上面的ls,就是只能接收参数,不能接收标准输入。像cat命令或echo命令,这些是可以的。

    怎么分辨一个命令可不可以接收标准输入?很简单,当你敲完命令回车后,终端会等待接收你的输入,例如当你在终端输入cat后,终端会等待你输入字符,当你输入一些字符后,然后按Ctrl-C发送终止符号。这时cat命令接收标准输入完毕,执行命令,也就是将刚才键入的内容输出的标准输出上(屏幕)。

    管道

    管道的作用是将前面命令的标准输出作为后面命令的标准输入。这里要注意,后面的命令接收的是标准输入,所以如果命令不支持接收标准输入,那么就不能直接使用管道,例如常用的ls命令,只能使用参数,而不能使用标准输入,所以[command] | ls是不能使用的。而命令如echocat就可以。那么肯定有方法来实现这些不能使用标准输入的命令与管道结合,这时候xargs便出场了。

    xargs命令

    xargs命令通俗来讲就是将标准输入转成各种格式化的参数,所以命令[command 1] | xargs [command 2]就是将command 1的标准输出结果,通过管道|变成xargs的标准输入,然后xargs再将此标准输入变成参数,传给[command 2]。这样一来,通过xargs命令,我们便可以在管道后面使用那些不接收标准输入的命令了。例如[command 1]|xargs ls,是不是很熟悉?

    find与grep

    有了以上的知识点,到这里终于可以解答最开始的问题了。为什么命令:

    find . -name '*.py' |grep test

    find . -name '*.py' |xargs grep test

    的结果是不一样的了。

    我们首先来查看grep手册。通过man grep命令:

    DESCRIPTION
           grep searches the named input FILEs (or standard input if no files are named, or if a single hyphen-minus (-) is given as file name) for lines containing a match to the given PATTERN.  
    By default, grep prints the matching lines.

    可以看到grep是支持标准输入的。

    假设目录存在如下文件:

    $ ls
    Altitest.py  python.py  runora.py  test.py  TransferFile.py

    那么对于第一个命令:find . -name '*.py' |grep test,是将前面命令的标准输出作为标准输入传给了grep test,那么grep是从这些标准输入寻找test字符,也就是文件名组成的字符流。

    $ find . -name '*.py' |grep test
    ./Altitest.py
    ./test.py

    可以看到最终选择出的是这些文件名。

    而对于第二个命令:find . -name '*.py' |xargs grep test,通过xargsfind得到的文件名成为了参数传给后面的grep,那么这时候这些文件名就是实实在在的文件标识,grep接收后会按正常的使用方式在各文件中搜寻字符串。

    #find . -name '*.py' |xargs grep test
    ./runora.py:testConn = cx_Oracle.connect('user/passwd@tns')
    ./runora.py:testCursor = testConn.cursor()
    ./runora.py:testCursor.execute("select * from table")
    ./runora.py:rows = testCursor.fetchall()
    ./runora.py:testCursor.close()
    ./runora.py:testConn.close()

    到这里算是将findgrepxargs和管道的作用理解清楚了。

    转自:http://fatmouse.xyz/2016/05/10/2016-05-10-find-grep-xargs-and-pipe/

  • 相关阅读:
    【Oracle】导入导出操作
    高德交通态势地址
    UML类图Java
    【SQL】数据库模糊查询
    【数据库】Java中数据库连接池原理机制的详细讲解
    随笔-使用时间管理有感
    【structs2】>>> FilterDispatcher <<< is deprecated!
    【算法】排序算法之插入排序
    【CSS】命名规范
    【JQuery】15个值得开发人员关注的jQuery开发技巧和心得
  • 原文地址:https://www.cnblogs.com/wangwust/p/10032275.html
Copyright © 2020-2023  润新知