搜索
查看: 1992|回复: 0

[linux] find和xargs连用虽好,但用起来要小心哦~

[复制链接]

33

主题

46

帖子

230

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
230
发表于 2017-2-21 19:41:02 | 显示全部楼层 |阅读模式
注:本文是生信媛微信公众号原创文章
作者:天地本无心
原文链接:
http://mp.weixin.qq.com/s?__biz=MzI1MjU5MjMzNA==&mid=2247483791&idx=1&sn=7d5a88b8ae83231082142ad31e773342&chksm=e9e0282ede97a1388d1954ab94f2c58d5aeb457a9bfa435b44af23f91c6b24ae812da8862f2e#rd




上一篇公众号文章,前面讲了很多故事和八卦,但通篇最重要的一点就是用rm -fr softlinkrm -fr softlink/根本就是两个效果完全不同的命令,希望能给自动补全党带来一点点启示意义。今天的一条导致危险的命令也和rm -fr有关,但是主角不是它,是xargs。

find . -name "*.fasta" | xargs wc -l

比如我们在linux shell tricks for bioinformatics I里面提到的一条指令,这行命令可以统计当前文件夹下,所有的fasta文件的行数。xargs在里面的意义就是将fasta文件的名字,一个一个地传递给wc -l命令。

那我们再看看下面的一条命令:
不安全命令,非错误命令:
find . -maxdepth 1 -name "*.txt" | xargs rm -fr
这个命令也许会达到你的目的。但是,一次能够正确执行你想要的操作,并不代表这个命令每次都能如你所愿。并且事实上,这条命令是非常危险的!

小伙伴请想象一下这个场景: 你辛辛苦苦做了三年生信,好容易攒了很多代码和Pipeline。把这些东西放在你的干活的电脑的Code和Pipeline的文件夹。你师兄毕业了,好心的他决定把他的代码给你,他拷给你好多文件夹,叫Zhaocheng Code,Zhaocheng Pipeline, Zhaocheng BlaBla等等。因为个人喜好缘故,他喜欢用空格来分隔文件名里的字符串。然后你点进去一看,全部是perl(破)代码。作为python爱好者的你,决定将它弃之如敝履。

来,跟着我的操作做一个测试。

find ./ -maxdepth 1 -name "*Zhaocheng*" | xargs rm -fr

运行完这句shell命令之后,你发现你想删掉的zhaocheng Code,zhaocheng Pipeline, zhaocheng BlaBla文件夹还在,你自己积攒的Code, Pipeline反而被删了! 此刻你的内心,想必一定是一万头神兽飘过。稍微平静一点之后呢,我们来试图理解一下其中的原因。

前面的都是些不痛不痒的,下面的几句话希望大家能够牢记。

1. xargs的默认定界符是空格。
2. 空字符(Null character)又称结束符,缩写NUL,是一个数值为0的控制字符。编程语言会自动在字符串结尾加上结束符,不需由程序员自己打上去。
当你find到了Zhaocheng Code之后,通过xargs传递给rm -fr时,因为xargs的默认定界符是空格。xargs会将Zhaocheng Code拆分成rm -fr Zhaocheng和rm -fr Code。然后这就是为什么你想删掉的没有删掉,而不想删的却误删了的原因。这种情况不一定每次都能碰到,但是有一种情况风险是非常高的。就是删除文献的时候,你想一下,文献的题目都是空格分开的,如果某一个字段正好跟你的文件夹重名,那就真的哔了狗了。

那这么说来,这个命令是不是不能用了啊。

其实还是能够用的。只需要指定定界符,将定界符制定为字符串的结束符null字符串就行。这样可以在xargs命令中,以null字符串(\0),也就是结束符来分隔输入参数,但find找到了Zhaocheng Code这个文件夹之后,是将这个名称整体地传递给rm -fr Zhaocheng Code来执行,这样就规避了空格作为定界符带来的风险。命令如下:

find  ./ -maxdepth 1 -name "*Zhaocheng*" -print0  | xargs -0  rm -fr

也有其它的方法:
find  ./ -maxdepth 1 -name "*Zhaocheng*" | xargs -I {}  rm -fr {}
或者
find . -maxdepth 1 -name "*Zhaocheng*"   -exec rm -fr {} \;

这样就能规避风险,当然方法还有很多很多,比如说,先将文件或者文件名里的空格全部替换为下划线,然后再执行操作。虽然这方法笨了点,但是非常稳妥。

最后还有一个建议,就是文件夹或者文件名里不要人为地加入空格,强迫症患者看着难受,空格全部用下划线代替。

PS: 二月已经跑步120公里,加油,奔跑的天地本无心!


欢迎到微信公众号订阅我们
生信媛
bio_sxy






上一篇:我谨慎地使用了rm -fr,为什么还是导致了灾难?
下一篇:小白生信学习记(三)转录组分析流程
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|生信技能树 ( 粤ICP备15016384号  

GMT+8, 2019-11-21 04:56 , Processed in 0.028930 second(s), 27 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.