rm 命令与 xargs 一起使用以排除名称中具有 space 的某些文件夹
rm command to be use with xargs to exclude some folders having space in the name
在一个目录中,我有大约 50 个文件和文件夹,其中包括一些名称中带有 space 的文件夹。我想使用 ls、grep 和 xargs 命令删除一些文件夹,但无法删除名称中带有 space 的文件夹并显示异常。谁能帮忙?使用 Solaris OS。
我在下面尝试删除除 $files
之外的所有内容
ls | grep -v "$文件" | xargs rm
当我尝试下面的命令时,它删除了所有内容,包括我不想要的 $files。
ls | grep -v "$文件" | xargs rm --*\ *
类 Unix 系统允许任何字符出现在文件名中,但 ASCII NUL 字符和斜杠除外。斜杠可以出现在路径名中(作为目录分隔符),但不能出现在实际目录条目的名称中。这意味着 xargs
读取的文件列表实际上可能包含白色 space 字符 – space、制表符和换行符。由于默认情况下,xargs
假定它正在读取的文件列表使用白色 space 作为参数分隔符,因此它无法正确处理文件名实际包含白色 space 的情况。这使得 xargs
的默认行为几乎无法处理任意数据。
为了解决这个问题,GNU findutils 为查找引入了“-print0”操作。这使用 ASCII NUL 字符来分隔它生成的文件列表中的条目。这是分隔符的理想选择,因为它是唯一不能出现在路径名中的字符。 xargs
的“-0”选项使其假定参数用 ASCII NUL 分隔而不是白色 space。它还关闭了 xargs
默认行为中的另一个错误功能,即它会注意输入中的引号字符。 xargs
的某些版本在输入中看到单独的“_”时也会终止,但 GNU find 不再这样做(因为它已成为 Unix 标准中的可选行为)。
所以,将 find -print0 与 xargs -0 放在一起,我们得到这个命令:
find /var/tmp/stuff -mtime +90 -print0 | xargs -0 /bin/rm
结果是一种有效的处理方式,可以正确处理所有可能出现在要删除的文件列表中的字符。这是个好消息。然而,正如我相信您所预料的那样,还有更多的坏消息。问题是这不是一个可移植的结构;尽管其他版本的 Unix(尤其是 BSD 派生的)支持“-print0”,但它并不通用。
除非使用 -r
选项(递归),否则无法使用 rm
命令删除文件夹。我假设你想删除单个文件,而不是整个目录。
在任何情况下,您都可以使用 Solaris 始终可用的标准 find
命令处理具有任意名称的文件和目录。 xargs
和 GNU 特定扩展都不是必需的。
这是一个例子。除了后缀为 .jpg 或 .java 的文件,以及名称中包含 keepme 的文件将被保留,所有剩余文件将被处理:
find . -type f ! -name "*.jpg" ! -name "*keepme*" ! -name "*.java" -exec echo rm {} +
如果您希望实际执行文件删除,请删除 echo
命令。
在不使用非标准扩展的情况下,假设您的 shell 实现了 while read ...
,这也应该有效:
ls | grep -v "$files" | while read filename; do
rm "$filename"
done
$filename
周围的引号很重要。如果没有引号,参数将根据名称中可能存在的任何空格进行拆分。
另请注意,这不会删除目录 - 正如其他人提到的,您需要 rm -r
- 或 rmdir
- 才能执行此操作。但是 rm -r
将删除一个目录 以及其中的所有内容 。 rmdir
默认情况下不会删除非空目录。
您可能应该 运行 先用
之类的东西进行测试
ls | grep -v "$files" | while read filename; do
ls -ld "$filename"
done
使用 -ld
选项到 ls
以确保您获得正确的文件,并且 不 列出目录内容如果文件传递的名称恰好是一个目录。
在一个目录中,我有大约 50 个文件和文件夹,其中包括一些名称中带有 space 的文件夹。我想使用 ls、grep 和 xargs 命令删除一些文件夹,但无法删除名称中带有 space 的文件夹并显示异常。谁能帮忙?使用 Solaris OS。 我在下面尝试删除除 $files
之外的所有内容ls | grep -v "$文件" | xargs rm
当我尝试下面的命令时,它删除了所有内容,包括我不想要的 $files。
ls | grep -v "$文件" | xargs rm --*\ *
类 Unix 系统允许任何字符出现在文件名中,但 ASCII NUL 字符和斜杠除外。斜杠可以出现在路径名中(作为目录分隔符),但不能出现在实际目录条目的名称中。这意味着 xargs
读取的文件列表实际上可能包含白色 space 字符 – space、制表符和换行符。由于默认情况下,xargs
假定它正在读取的文件列表使用白色 space 作为参数分隔符,因此它无法正确处理文件名实际包含白色 space 的情况。这使得 xargs
的默认行为几乎无法处理任意数据。
为了解决这个问题,GNU findutils 为查找引入了“-print0”操作。这使用 ASCII NUL 字符来分隔它生成的文件列表中的条目。这是分隔符的理想选择,因为它是唯一不能出现在路径名中的字符。 xargs
的“-0”选项使其假定参数用 ASCII NUL 分隔而不是白色 space。它还关闭了 xargs
默认行为中的另一个错误功能,即它会注意输入中的引号字符。 xargs
的某些版本在输入中看到单独的“_”时也会终止,但 GNU find 不再这样做(因为它已成为 Unix 标准中的可选行为)。
所以,将 find -print0 与 xargs -0 放在一起,我们得到这个命令:
find /var/tmp/stuff -mtime +90 -print0 | xargs -0 /bin/rm
结果是一种有效的处理方式,可以正确处理所有可能出现在要删除的文件列表中的字符。这是个好消息。然而,正如我相信您所预料的那样,还有更多的坏消息。问题是这不是一个可移植的结构;尽管其他版本的 Unix(尤其是 BSD 派生的)支持“-print0”,但它并不通用。
除非使用 -r
选项(递归),否则无法使用 rm
命令删除文件夹。我假设你想删除单个文件,而不是整个目录。
在任何情况下,您都可以使用 Solaris 始终可用的标准 find
命令处理具有任意名称的文件和目录。 xargs
和 GNU 特定扩展都不是必需的。
这是一个例子。除了后缀为 .jpg 或 .java 的文件,以及名称中包含 keepme 的文件将被保留,所有剩余文件将被处理:
find . -type f ! -name "*.jpg" ! -name "*keepme*" ! -name "*.java" -exec echo rm {} +
如果您希望实际执行文件删除,请删除 echo
命令。
在不使用非标准扩展的情况下,假设您的 shell 实现了 while read ...
,这也应该有效:
ls | grep -v "$files" | while read filename; do
rm "$filename"
done
$filename
周围的引号很重要。如果没有引号,参数将根据名称中可能存在的任何空格进行拆分。
另请注意,这不会删除目录 - 正如其他人提到的,您需要 rm -r
- 或 rmdir
- 才能执行此操作。但是 rm -r
将删除一个目录 以及其中的所有内容 。 rmdir
默认情况下不会删除非空目录。
您可能应该 运行 先用
之类的东西进行测试ls | grep -v "$files" | while read filename; do
ls -ld "$filename"
done
使用 -ld
选项到 ls
以确保您获得正确的文件,并且 不 列出目录内容如果文件传递的名称恰好是一个目录。