我们通常在使用find
的时候,会再加个xargs
来搭配使用。
但是我在群里面的看到的常用的搭配命令里面,却对空格,这样子的分隔符不做处理。
问题
例如,这个样子的
1find . -type f -name '*.txt' | xargs rm -f
这样子就明显是对空格没有做好处理。
这样子会到导致啥问题?
现在新建两个文件,te
te ddd.txt
1touch te
2touch 'te ddd.txt'
看一下现在目录下面有什么文件
1$ ls
2
3te te ddd.txt
现在来执行,上面所述的有问题代码。
1
2$ find . -type f -name '*.txt' | xargs rm -f
3
4$ ls
5
6te ddd.txt
可以见到这个出了问题。
find + xargs
这命令原本是为了删掉所有的txt文件—te ddd.txt
。
但是却没有删到需要删除的文件,却是把需要的文件te
给删除了。
所以这个问题,是需要我们去解决的。
原因
出现这个问题的原因,其实很简单。
xargs
会对于stdin输入
的数据进行解析,默认是使用空白字符(就是空格)进行分割,然后执行echo
命令。
在这种默认情况下,如果目录名或者文件名出现空格,就会出现字符串分裂这种情况。
就像刚刚那个例子一样,te ddd.txt
»> te
ddd.txt
。
直接分成了两部分,而te
直接传给了rm
,被直接删了。
解决方案
需要的肯定的是,这种情况,人家在开发的时候就已经想到了这个问题。
而我们需要的就只是改变一下分割时候的分割符,就是不用空格进行分割。
我们只需要使用 find
的一个option
–-print0
,xargs的一个option
–-0
。
find
的 -print0
,可以使用0(NULL)
作为分隔查找到的元素。
xargs
的 -0
,则是会使用0(NULL)
来解析数据。
所以只需要把命令加两个option
就行了。
1find . -type f -name '*.txt' -print0 | xargs -0 rm -f
执行一下
1$ ls
2
3te ddd.txt
4
5$ find . -type f -name '*.txt' -print0 | xargs -0 rm -f
6
7$ ls
8
Tips: xargs
可以使用-d
来指定分隔符。