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

时间:2008-12-28 14:01:57

标签: macos unix list shell file

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

它应该是这样的:对于f in $(ls -1);回声$ f;完成

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

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

如果我这样做:f in $(ls -1);回声$ f; DONE 我得到:文件A.txt \ nfile B.txt

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

6 个答案:

答案 0 :(得分:12)

尽可能远离ls。使用findutils包中的find。

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替换为您将用于处理文件名的命令。 (注意:如果你使用echo为your_command_here从shell运行它,你将获得一行上的所有东西 - 不要被那个shell工件搞糊涂,xargs无论如何都会做正确的事情。)

编辑:或者(或者如果你没有xargs),你可以使用效率低得多的

find /target/path -type f -exec your_command_here \{\} \;

\{\} \;{} ;的转义符,它是当前处理文件的占位符。然后,find将调用your_command_here并将{} ;替换为文件名,并且由于your_command_here将由find而不是shell启动,因此空格无关紧要。

第二个版本的效率会降低,因为find会为找到的每个文件启动一个新进程。 xargs足够智能,可以将命令传递给新启动的进程,如果它能够确保安全的话。如果您有选择,请更喜欢xargs版本。

答案 1 :(得分:10)

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

应该做你想做的事。您为什么使用ls代替*

通常,处理shell中的空格是PITA。看看$IFS变量,或者更好的是Perl,Ruby,Python等。

答案 2 :(得分:2)

以下是 derobert 讨论的使用$ IFS的答案 http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html

答案 3 :(得分: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

答案 4 :(得分:0)

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

  

$ ls --quoting-style = c

     

“file1”“file2”“dir one”

答案 5 :(得分:-1)

查看xargs的联机帮助页:

它的工作原理如下:

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