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

17 浏览
0 Comments

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

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

IFS=$'\0';find people -name '*.svg' -print0 | while read file; do

grep ' /dev/null && echo $file | tee -a embeded_images.txt;

done

我试图找到包含嵌入图像的所有svg文件,如果没有使用-print0它可以工作,但是有一个文件失败了,所以我停止了脚本。这是一个不工作的简单示例:

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

它没有显示任何内容。

0
0 Comments

问题的原因是在使用Bash的find命令遍历文件时,如果文件名包含空格,会导致read命令无法正确读取文件名。解决方法是使用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

为什么read -d'' -r file; do不起作用,但是加上空格的-d ''却可以起作用呢?

原因是单引号中的内容为空。Bash将-d''视为一个参数。当执行引号删除时,除了-d之外什么都没有了。而-d ''被视为两个参数,其中一个为null。

0
0 Comments

循环遍历Bash中包含空格的文件名输出的问题是由于在循环中创建了子shell导致的。这会导致无法在循环中设置任何变量。为了解决这个问题,可以考虑使用进程替代(process substitution)。

具体解决方法如下:

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

上述代码中,第一个`<`表示从一个文件中读取输入,而`<(find...)`则被替换为一个返回`find`命令输出的文件名(通常是一个管道句柄)。由于`while`从文件而不是管道中读取,因此循环可以设置在作用域外访问的变量。

0