find与xargs对于空格分隔符的处理问题

我们通常在使用find的时候,会再加个xargs来搭配使用。

但是我在群里面的看到的常用的搭配命令里面,却对空格,这样子的分隔符不做处理。

问题

例如,这个样子的

1
find . -type f -name '*.txt' | xargs rm -f

这样子就明显是对空格没有做好处理。

这样子会到导致啥问题?

现在新建两个文件,te te ddd.txt

1
2
touch te
touch 'te ddd.txt'

看一下现在目录下面有什么文件

1
2
3
$ ls

te te ddd.txt

现在来执行,上面所述的有问题代码。

1
2
3
4
5
6

$ find . -type f -name '*.txt' | xargs rm -f

$ ls

te 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就行了。

1
find . -type f -name '*.txt' -print0 | xargs -0 rm -f

执行一下

1
2
3
4
5
6
7
$ ls

te ddd.txt

$ find . -type f -name '*.txt' -print0 | xargs -0 rm -f

$ ls

Tips: xargs 可以使用-d来指定分隔符。

0%