在Bash中循环遍历包含空格的文件名的find输出

21

我尝试搜索可能包含空格的文件,我尝试使用-print0并设置IFS,以下是我的脚本:

IFS=$'\0';find people -name '*.svg' -print0 | while read file; do
    grep '<image' $file > /dev/null && echo $file | tee -a embeded_images.txt;
done

我试图查找包含嵌入式图像的所有svg文件,如果不使用-print0,则可以正常工作,但是当遇到一个文件时会失败,因此我停止了脚本。这里是一个简单的示例,它也无法正常工作。

IFS=$'\0';find . -print0 | while read file; do echo $file; done

它没有显示任何内容。

2个回答

29

虽然Dennis Williamson的回答是绝对正确的,但它 会创建子shell,从而阻止您在循环内设置任何变量。您可以考虑使用进程替换,如下所示:

while IFS= read -d '' -r file; do
    grep '<image' "$file" > /dev/null && echo "$file" | tee -a embeded_images.txt
done < <(find people -name '*.svg' -print0)

第一个<表示您正在从文件中读取,而<(find...)被替换为文件名(通常是管道的句柄),该管道返回直接从find输出的内容。由于while从文件而不是管道读取,因此您的循环可以设置可以从范围外访问的变量。


27

使用 read -d '' -r file 命令,并只在 read 上下文中设置 IFS

find people -name '*.svg' -print0 | while IFS= read -d '' -r file; do
    grep '<image' "$file" > /dev/null && echo "$file" | tee -a embeded_images.txt;
done

并将您的变量加上引号。


@IFS= read@ 方法在以空格结尾的文件上成功。 - faxmodem
奇怪的 read -d'' -r file; do 不起作用,但是加上空格 -d '' 就可以了。 - jcubic
2
@jcubic:单引号中的内容为空。Bash将-d''视为一个参数。当它执行引号移除时,除了-d之外什么也没有了。它将-d ''视为_两个_参数,其中一个为空。 - Dennis Williamson

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