How to prevent filename expansion in for loop in bash

人走茶凉 提交于 2019-12-04 03:46:25

问题


In a for loop like this,

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

if one of the input file contains entries like *a, it will, and give the filenames ending in 'a'.

Is there a simple way of preventing this filename expansion?

Because of use of multiple files, globbing (set -o noglob) is not a good option. I should also be able to filter the output of cat to escape special characters, but

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

still causes *a to expand, while

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

gives me \*a (including backslash). [ I guess this is a different question though ]


回答1:


This will cat the contents of all the files and iterate over the lines of the result:

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

If the files contain globbing characters, they won't be expanded. They keys are to not use for and to quote your variable.

In Bourne-derived shells that do not support process substitution, this is equivalent:

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

The reason not to do that in Bash is that it creates a subshell and when the subshell (loop) exits, the values of variables set within and any cd directory changes will be lost.




回答2:


For the example you have, a simple cat *.input will do the same thing.



来源:https://stackoverflow.com/questions/5111760/how-to-prevent-filename-expansion-in-for-loop-in-bash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!