如何在Unix中处理包含空格的文件名列表?

4

我想在Mac OS X提示符中列出目录中的文件并对它们执行某些操作。

应该像这样进行:for f in $(ls -1); do echo $f; done

如果我的文件名中没有空格(fileA.txt,fileB.txt),则echo可以正常工作。 如果文件名包含空格(“file A.txt”,“file B.txt”),则会得到4个字符串(file,A.txt,file,B.txt)。

我尝试过引用列表命令,但它只改变了问题。

如果我这样做:for f in $(ls -1); do echo $f; done 我得到:file A.txt\nfile B.txt

(它正确显示,但它是一个单独的字符串,我需要分开2行。)

6个回答

12
如果可能的话,尽量避免使用ls命令,并使用findutils软件包中的find命令。
用以下命令替换your_command_here,并在/target/path下查找文件:
find /target/path -type f -print0 | xargs -0 your_command_here -print0会导致find输出以NUL字符(ASCII零)分隔的名称。xargs的-0参数告诉它也要期望以NUL字符分隔的参数,所以一切都会正常工作。
/target/path替换为包含您的文件的路径。 -type f仅定位文件。使用-type d查找目录,或者完全省略以获取两者都是。
your_command_here替换为用于处理文件名的命令。
如果没有xargs,或者您更喜欢其他替代方案,则可以使用效率低得多的以下命令:
find /target/path -type f -exec your_command_here \{\} \; \{\} \;{} ;的转义符,它是当前正在处理的文件的占位符。然后,find将使用文件名替换{} ;调用your_command_here,并且由于your_command_here将由find而不是shell启动,因此空格并不重要。
第二个版本的效率会稍低,因为find将为找到的每个文件启动一个新进程。如果xargs可以确定安全地这样做,则xargs足够聪明,可以将命令管道传递到新启动的进程中。如果可以选择,优先使用xargs版本。

如果您需要在一个文件上运行多个命令,xargs 的效果可能不是很好。当然,您可以使用 shell 脚本作为单个命令。 - derobert
没错。在find命令中,总是可以使用-exec参数(不过,正如你所指出的那样,大多数问题都可以通过使用xargs和一个单独的shell脚本来重新表述)。 - Mihai Limbășan

10
for f in *; do echo "$f"; done

使用 * 而不是 ls 应该能够实现您想要的功能。一般来说,处理 shell 中的空格很麻烦。可以查看 $IFS 变量,或者更好的方法是使用 Perl、Ruby、Python 等语言。


如果只需要一个简单的ls -1命令,那么可以用*代替它。但是,OP可能有其他需求,例如在按时间修改顺序处理文件时,我经常遇到这个问题。 - James Brady
无论何时您使用ls,都会遇到这个问题,因为文件名可能包含换行符。您需要切换到其他方法(例如,find / xargs、perl / ruby / python、bash数组+大量工作)。 - derobert

2

0

查看--quoting-style选项。 例如,--quoting-style=c将产生:

$ ls --quoting-style=c

"file1" "file2" "dir one"


0

您可以将参数导入 read 中。例如,要 cat 目录中的所有文件:

ls -1 | while read FILENAME; do cat "$FILENAME"; done

这意味着您仍然可以使用像在您的问题中一样的ls或任何其他生成$IFS分隔输出的命令。

while循环使对参数执行多个操作变得更加容易,并且在我看来,它使复杂处理更易读。一个刻意的例子:

ls -1 | while read FILE
do
    echo 1: "$FILE"
    echo 2: "$FILE"
done

如果只有空格(和制表符),那么这很有帮助;但如果名称中有换行符,则无济于事。在这种情况下,find -print0 和 xargs -0 很有帮助。 - Jonathan Leffler

-1

查看 xargs 的 man 手册:

它的工作方式如下:

ls -1 /tmp/*.jpeg | xargs rm


这只是答案的一小部分 - 如果没有更完整的解释,你的回答就没有任何帮助。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接