xargs和find,rm抱怨文件名中的\n(换行符)
xargs和find,rm抱怨文件名中的\n(换行符)
我正在尝试使用Debian中的脚本删除树中最旧的文件。\n
find /home/backups -type f \( -name \*.tgz -o -name \*.gz \) -print0 | xargs -0 ls -t | tail -1 | xargs -0 rm
\n但是我遇到了一个错误:\n
rm: 无法删除“/home/backups/tree/structure/file.2011-12-08_03-01-01.sql.gz\n”:没有那个文件或目录
\n有什么想法我在做错了什么(或者有没有更简单/更好的方法?),我已经尝试了RTFM,但是还是迷失了。
问题:xargs和find命令在删除带有换行符(\n)的文件名时报错。
原因:ls命令的输出中使用换行符作为分隔符,因此需要将第二个xargs -0替换为xargs -d '\n'。然而,如果最旧的文件名中包含换行符,这种方法将失效。
解决方法:使用find命令的-exec选项来替代xargs命令,这样可以避免由于文件名中包含换行符而导致的问题。具体操作如下:
find . -type f -print0 | xargs -0 rm
上述命令将在当前目录下删除所有文件,包括文件名中包含换行符的文件。通过使用-print0选项和xargs -0命令,可以确保文件名正确地传递给rm命令,从而避免报错。
另外一种解决方法是使用find命令的-delete选项,它会自动删除找到的文件,无需使用xargs命令。具体操作如下:
find . -type f -delete
上述命令将在当前目录下删除所有文件,包括文件名中包含换行符的文件。
当使用xargs和find命令删除文件时,如果文件名中包含换行符,会导致报错。为了解决这个问题,可以使用xargs -d '\n'选项替代xargs -0,或者直接使用find命令的-exec选项或-delete选项来避免使用xargs命令。
在使用xargs和find命令时,有时会遇到"rm complaining about \n (newline) in filename"的问题。这个问题的出现原因是,ls命令会在每个文件名后面添加一个换行符,而最后的xargs -0命令表示换行符是文件名的一部分。
要解决这个问题,可以将最后的xargs命令的参数从"-0"改为"-d '\n'"。这样xargs命令将使用换行符作为分隔符而不是空格。
另外,由于xargs命令的工作方式,整个管道的设计存在一个潜在的bug。假设find命令产生了一个非常长的文件名列表,导致xargs -0 ls命令多次运行,并且每次只处理一部分文件名。在这种情况下,只有最早的那个ls命令会通过tail命令的筛选,其他的ls命令都被丢弃了。如果最早的文件名实际上是find命令输出的第一个文件名,那么你可能会误删一个比较新的文件。
此外,即使使用了"-d '\n'"参数,xargs命令仍然会以每个空格作为分隔符进行拆分,这可能不是你想要的结果。
在解决问题时,可以通过添加"-d '\n'"参数来避免换行符的问题。同时,还需要注意文件名列表的长度限制,如果文件名列表的总长度超过了系统设定的限制,xargs命令会多次调用相应的命令。
最后,如果仍然遇到无法找到文件的问题,可以尝试使用其他方法来查看具体的输出情况,例如使用xargs -d '\n' printf '*%s*\n' | cat -A命令来查看实际输出的文件名,看是否存在问题。