加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在for循环中使用任意glob模式(带空格)

发布时间:2020-12-16 01:36:02 所属栏目:安全 来源:网络整理
导读:有没有办法可靠地使用存储在变量中的任意globbing模式?如果模式包含空格和元字符,我会遇到困难.这就是我的意思.如果我有一个存储在没有空格的变量中的模式,那么事情似乎工作正常: prompt touch aa.{1,2,3} "a b".{1,3}prompt p="aa.?"prompt for f in ${p}
有没有办法可靠地使用存储在变量中的任意globbing模式?如果模式包含空格和元字符,我会遇到困难.这就是我的意思.如果我有一个存储在没有空格的变量中的模式,那么事情似乎工作正常:
<prompt> touch aa.{1,2,3} "a b".{1,3}
<prompt> p="aa.?"
<prompt> for f in ${p} ; do echo "|$f|" ; done
|aa.1|
|aa.2|
|aa.3|
<prompt> declare -a A=($p) ; for f in "${A[@]}" ; do echo "|$f|" ; done
|aa.1|
|aa.2|
|aa.3|

但是,只要我在模式中抛出一个空格,事情就变得站不住脚了:

<prompt> p="a b.?"
<prompt> for f in ${p} ; do echo "|$f|" ; done
|a|
|b.?|
<prompt> declare -a A=($p) ; for f in "${A[@]}" ; do echo "|$f|" ; done
|a|
|b.?|
<prompt> for f in "${p}" ; do echo "|$f|" ; done
|a b.?|
<prompt> for f in $(printf "%q" "$p") ; do echo "|$f|" ; done
|a|
|b.?|

显然,如果我事先知道模式,我可以手动逃避它:

<prompt> for f in a b.* ; do echo "|$f|" ; done
|a b.1|
|a b.2|
|a b.3|

问题是,我正在写一个脚本,我不提前知道这个模式.有没有办法可靠地使bash将变量的内容视为一个globbing模式,而不采用某种eval技巧?

你需要关闭分词.回顾一下,这不起作用:
$p="a b.?"
$for f in ${p} ; do echo "|$f|" ; done
|a|
|b.?|

但是,这样做:

$( IFS=; for f in ${p} ; do echo "|$f|" ; done )
|a b.1|
|a b.2|
|a b.3|

IFS是shell的“内部字段分隔符”.它通常设置为空格,制表符和换行符.它用于变量扩展后的单词拆分.将IFS设置为空会停止分词,从而允许glob工作.

数组示例

这同样适用于数组示例:

$declare -a A=($p) ; for f in "${A[@]}" ; do echo "|$f|" ; done
|a|
|b.?|
$( IFS=; declare -a A=($p) ; for f in "${A[@]}" ; do echo "|$f|" ; done )
|a b.1|
|a b.2|
|a b.3|

确保IFS恢复到正常值

在上面的示例中,我将IFS赋值放在子shell中.尽管不是必需的,但优点是IFS在子shell终止后自动返回其先前值.如果子壳不适合您的应用,这是另一种方法:

$oldIFS=$IFS; IFS=; for f in ${p} ; do echo "|$f|" ; done; IFS=$oldIFS
|a b.1|
|a b.2|
|a b.3|

匹配模式与shell-active字符

假设我们的名称中包含文字*的文件:

$touch ab.{1,3} 'a*b'.{1,3}
$ls
a*b.1  ab.1  a*b.2  ab.2  a*b.3  ab.3

而且,假设我们想匹配那颗星.既然我们希望明星得到真正的对待,我们必须逃避它:

$p='a*b.?'
$( IFS=; for f in ${p} ; do echo "|$f|" ; done )
|a*b.1|
|a*b.2|
|a*b.3|

因为?没有转义,它被视为通配符.因为*是转义的,所以它只匹配文字*.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读