首页 > 解决方案 > for 循环遍历名称中带有空格的文件

问题描述

我有一个目录或压缩文件,每个都包含一组 XML 文件我需要制作一个脚本,如果这些 ZIP 包含某个字符串,它将从这些 ZIP 中提取 XML 文件

for z in `ls /path/to/archives/*.zip`
do for f in `unzip -l $z | grep 'xml' | awk -F" " '{print "$4" "$5}'`
  do r = $( unzip -p $z $f | grep $string )
    if [ '$r' != '' ]
    unzip $z $f
    fi
  done
done

当它运行时,包含名为“my file.xml”的文件的压缩文件 A.zip 会导致循环将其作为 2 个文件“my”和“file.xml”解压缩然后尝试从 A.zip 中提取文件 my 失败

关于如何强制 for 循环不将文件名中的空格视为分隔符的任何想法?

标签: bashfor-loopspace

解决方案


使用-Z1选项unzip而不是-l。它每行输出一个文件,没有附加信息。您应该阅读它的输出而不是使用 for 循环它以防止分词。您可能仍然对包含换行符的文件名有问题(但我无法压缩它们,$'a\nb'存储为a^Jb并提取为ab)。

另外,您if缺少一个then.

另外,不要解析 的输出ls,您可以遍历全局文件掩码本身。

您无需检查grep输出任何内容,只需运行它-q并检查其退出状态。

不要忘记对可能包含空格或其他特殊字符的变量加双引号。

for z in /path/to/archives/*.zip ; do
    while IFS= read -r f ;  do
        if unzip -p "$z" "$f" | grep -q "$string" ; then
            unzip "$z" "$f"
        fi
    done < <(unzip -Z1 "$z" '*.xml')
done

推荐阅读