【问题标题】:for loop through files with spaces in their namesfor 循环遍历名称中带有空格的文件
【发布时间】:2018-11-07 10:53:50
【问题描述】:

我有一个目录或压缩文件,每个都包含一组 XML 文件 我需要制作一个脚本,如果它们包含某个字符串,将从这些 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”处理 unzip 然后尝试从 A.zip 中提取文件 my 失败

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

【问题讨论】:

    标签: bash for-loop space


    【解决方案1】:

    使用unzip-Z1 选项而不是-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
    

    【讨论】:

    • 好剧本!顺便说一句,while IFS= read -r fwhile read f 更安全。
    • 来说他错过了空格的引号,并留下了性感的脚本。 +1
    • 工作就像一个魅力!谢谢 choroba、Kamil Cuk 和 MeetTitan :) +1(虽然 stackoverflow 不会显示)
    猜你喜欢
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多