【问题标题】:How to prevent filename expansion in for loop in bash如何防止bash中for循环中的文件名扩展
【发布时间】:2011-07-03 23:06:24
【问题描述】:

在这样的for循环中,

for i in `cat *.input`; do
    echo "$i"
done

如果输入文件之一包含像*a 这样的条目,它会,并给出 以“a”结尾的文件名。

有没有一种简单的方法可以防止这种文件名扩展?

由于使用多个文件,通配符 (set -o noglob) 不是 不错的选择。我还应该能够将cat 的输出过滤为 转义特殊字符,但是

for i in `cat *.input | sed 's/*/\\*'`
    ...

仍然会导致 *a 扩展,而

for i in `cat *.input | sed 's/*/\\\\*'`
    ...

给我\*a(包括反斜杠)。 [我想这是一个不同的 问题虽然]

【问题讨论】:

  • 您想对输入文件中的每一行或每个单词做些什么吗?因为如果输入文件之一包含例如foo bar.txt 然后 for 循环将执行一次迭代,将 i 设置为 foo,并进行一次迭代,将 i 设置为 bar.txt

标签: bash shell for-loop wildcard expansion


【解决方案1】:

对于你的例子,一个简单的cat *.input 会做同样的事情。

【讨论】:

  • 感谢和抱歉没有早点说明,但是这里的脚本太复杂了。 echo $i 只是一个占位符(for 循环中的cat 也是 grep/sed/cut 的复杂组合)。如果我能得到这个echo 语句来打印文件中的内容,剩下的就解决了。
【解决方案2】:

这将cat所有文件的内容并遍历结果的行:

while read -r i
do
    echo "$i"
done < <(cat *.input)

如果文件包含通配符,它​​们将不会被扩展。他们的关键是不要使用for 并引用你的变量。

在不支持进程替换的 Bourne 派生的 shell 中,这是等效的:

cat *.input | while read -r i
do
    echo "$i"
done

在 Bash 中不这样做的原因是它创建了一个子shell,当子shell(循环)退出时,其中设置的变量值和任何cd 目录更改都将丢失。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多