3

我有一个小脚本,它利用回声能力来生成元素的组合。就是这么一段代码

set={1,2,3,4}
group=3
for ((i=0; i<$group; i++));
do
  repetition=$set$repetition
done

bash -c "echo "$repetition""

效果很好,当我希望集合包含一些特殊字符(如逗号、括号等)时,问题就来了。我尝试过使用 scapes 但它似乎不起作用,比如

set={(,),\,,=}

关于如何实现它的任何线索?

4

2 回答 2

2

虽然@fedorqui 的答案是可行的,但这里有更多信息以确保完整性。您知道特殊字符需要转义,但\它本身就是一个特殊字符,因此需要转义,因为您要将它传递给另一个 bash 实例。

因此,当您set={(,)}在脚本中添加时,您的脚本会因为括号而引发语法错误。一旦你逃避它们,因为set={\(,\)}你的脚本对它们没问题,但在你将它们传递给你的时候已经扩展它们,bash -c而不是看到set={( )}并窒息,给出相同的语法错误:

$ set={\(,\)}; echo Parent: "$set";  bash -c "echo Child1: "$set""
Parent: {(,)}
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `echo Child1: {(,)}'

显而易见的解决方案是自己转义反斜杠,以便正确传递它们。但是,转义会导致角色失去其特殊能力,因此转义\将阻止其转义括号:

$ set={\\(,\\)};
bash: syntax error near unexpected token `('

所以,回到第一方。你需要做的是逃避逃逸逃逸1的逃逸:

$ set={\\\(,\\\)}
$ echo "Parent3: $set"
Parent3: {\(,\)}
$ bash -c "echo Child3 "$set""
Child3 ( )

在这里,子实例终于被传递了它需要看到的东西:{\(,\)}。因此,虽然在这种情况下使用引号并不是绝对必要的,但它们确实让您的生活变得更加轻松:


1试着快速说5次。

于 2014-10-03T15:25:49.747 回答
2

您需要引用和转义:

set={1,2,3,"\'4\'"}

请注意,它正在使用,{1,2,3,4}因为它是数字。对于字符串,您还需要引用:{1,2,3,'a'}

$ echo {1,2,3,'a'}{1,2,3,'a'}
11 12 13 1a 21 22 23 2a 31 32 33 3a a1 a2 a3 aa

然后转义是bash -c与值一起处理执行。


根据您的评论,您的最终脚本是:

set={"\(","\)","\,"}
group=3
for ((i=0; i<$group; i++));
do
  repetition=$set$repetition
done

bash -c "echo "$repetition""

当我执行它时,我得到了这个,很好!

$ ./a
((( (() ((, ()( ()) (), (,( (,) (,, )(( )() )(, ))( ))) )), ),( ),) ),, ,(( ,() ,(, ,)( ,)) ,), ,,( ,,) ,,,
于 2014-10-03T12:00:06.047 回答