zoukankan      html  css  js  c++  java
  • linux find命令中-print0和xargs中-0的用法

    linux find命令中-print0和xargs中-0的用法。

    1、默认情况下, find命令每输出一个文件名, 后面都会接着输出一个换行符 (' '), 因此find 的输出都是一行一行的:

     [bash-4.1.5] ls -l
      total 0
      -rw-r--r-- 1 root root 0 2010-08-02 18:09 file1.log
      -rw-r--r-- 1 root root 0 2010-08-02 18:09 file2.log
    [bash-4.1.5] find . -name '*.log'
      ./file2.log
      ./file1.log

    比如用find命令把所有的 .log 文件删掉, 可以这样配合 xargs 一起用:

    [bash-4.1.5] find . -name '*.log'
      ./file2.log
      ./file1.log
    [bash-4.1.5] find . -name '*.log' | xargs rm
    [bash-4.1.5] find . -name '*.log'
    find命令结合xargs 真的很强大. 然而:  

    [bash-4.1.5] touch "file 1.log"

    [bash-4.1.5] touch "file 2.log"

    [bash-4.1.5] ls -l
    total 0
    -rw-r--r-- 1 root root 0 2010-08-02 18:12 file 1.log
    -rw-r--r-- 1 root root 0 2010-08-02 18:12 file 2.log
    [bash-4.1.5] find -name '*.log'
    ./file 1.log
    ./file 2.log
    [bash-4.1.5] find -name '*.log' | xargs rm
    rm: cannot remove `./file': No such file or directory
    rm: cannot remove `1.log': No such file or directory
    rm: cannot remove `./file': No such file or directory
    rm: cannot remove `2.log': No such file or directory

    原因其实很简单, xargs 默认是以空白字符 (空格, TAB, 换行符) 来分割记录的, 因此文件名 ./file 1.log 被解释成了两个记录 ./file 和 1.log, 不幸的是 rm 找不到这两个文件. 如下:

    为了解决此类问题, 让 find命令在打印出一个文件名之后接着输出一个 NULL 字符 ('') 而不是换行符 (-print0), 然后再告诉 xargs 也用 NULL 字符来作为记录的分隔符 (xargs -0). 这就是 find 的 -print0 和 xargs 的 -0 的来历吧.

    [bash-4.1.5] ls -l
    total 0
    -rw-r--r-- 1 root root 0 2010-08-02 18:12 file 1.log
    -rw-r--r-- 1 root root 0 2010-08-02 18:12 file 2.log

    [bash-4.1.5] find -name '*.log' -print0 | hd           // 这里没看太懂,看懂的人请留言指教。
    0 1 2 3 4 5 6 7 8 9 A B C D E F |0123456789ABCDEF|
    --------+--+--+--+--+---+--+--+--+---+--+--+--+---+--+--+--+--+----------------|
    00000000: 2e 2f 66 69 6c 65 20 31 2e 6c 6f 67 00 2e 2f 66 |./file 1.log../f|
    00000010: 69 6c 65 20 32 2e 6c 6f 67 00 |ile 2.log. |
    [bash-4.1.5] find -name '*.log' -print0 | xargs -0 rm
    [bash-4.1.5] find -name '*.log'
     
    你可能要问了, 为什么要选 '' 而不是其他字符做分隔符呢? 这个也容易理解: 一般的编程语言中都用 '' 来作为字符串的结束标志, 文件的路径名中不可能包含 '' 字符.

    解释下为什么 find -name '*.log' -print0 | xargs -0 rm 能删除:

    先看 find -name '*.log' -print 的结果:

    在看先看 find -name '*.log' -print0 的结果如下,可以发现换行符变成了 ''

    然后看一下  find -name '*.log' -print0 | xargs -0 的输出结果:发现 xargs 将 '' 当作多条记录的分割符。

    因此 file 1.log 和 file 2.log 就被分开处理了, file 1.log 会被作为一个文件处理,file 1.log就不会被拆开为 file 和 1.log 两个文件了。

      

     至于为什么  file 1.log 和 file 2.log 会被分开处理,详情看这个文章

     此篇文章为转载,谢谢查看!

  • 相关阅读:
    责任
    人生
    有感
    冲突无处不在
    中科院玉泉路攻略——吃篇(校外)
    兄弟
    (18)[转载]:跳台阶问题
    Excel表格加下列选择框
    (转载)(c#)数据结构与算法分析 数组、向量和表
    [转载] 趣味算法:字符串反转的N种方法
  • 原文地址:https://www.cnblogs.com/xiaofeng666/p/10746243.html
Copyright © 2011-2022 走看看