我有一个黑名单来保存标签id列表,例如1-3,7-9
,实际上它代表1,2,3,7,8,9
。并可以通过下面的shell扩展它
for i in {1..3,7..9}; do for j in {$i}; do echo -n "$j,"; done; done
1,2,3,7,8,9
但首先,我应该将-
转换为..
echo -n "1-3,7-9" | sed 's/-/../g'
1..3,7..9
然后将其作为参数放入for
表达式中
echo -n "1-3,7-9" | sed 's/-/../g' | xargs -I @ for i in {@}; do for j in {$i}; do echo -n "$j,"; done; done
zsh: parse error near `do'
echo -n "1-3,7-9" | sed 's/-/../g' | xargs -I @ echo @
1..3,7..9
但是for
表达式无法正确解析它,这是为什么呢?
发布于 2016-12-23 10:33:59
因为您没有做任何事情来阻止最外层的shell拾取您想要由xargs
运行的特殊关键字和字符( do
、for
、$
等)。
xargs
不是一个内置的外壳;它从它的参数中获取您希望它为标准输入上的每个元素运行的命令行。就像任何其他程序一样,如果您希望;
或任何其他特殊序列在参数中是bash,则需要以某种方式对其进行转义。
在我看来,这里您真正想要的似乎是在子seems中为每个输入元素调用一个命令(嵌套的for
循环)。
我想出了这个;看起来很适合这份工作:
echo -n "1-3,7-9" \
| sed 's/-/../g' \
| xargs -I @ \
bash -c "for i in {@}; do for j in {\$i}; do echo -n \"\$j,\"; done; done;"
这就给出了:
{1..3},{7..9},
发布于 2016-12-24 20:10:27
可以使用下面的shell来实现这一点
# Mac newline need special treatment
echo "1-3,7-9" | sed -e 's/-/../g' -e $'s/,/\\\n/g' | xargs -I@ echo 'for i in {@}; do echo -n "$i,"; done' | bash
1,2,3,7,8,9,%
#Linux
echo "1-3,7-9" | sed -e 's/-/../g' -e 's/,/\n/g' | xargs -I@ echo 'for i in {@}; do echo -n "$i,"; done' | bash
1,2,3,7,8,9,
但是使用这种方式有点复杂,也许awk
更直观
# awk
echo "1-3,7-9,11,13-17" | awk '{n=split($0,a,","); for(i=1;i<=n;i++){m=split(a[i],a2,"-");for(j=a2[1];j<=a2[m];j++){print j}}}' | tr '\n' ','
1,2,3,7,8,9,11,13,14,15,16,17,%
发布于 2016-12-29 14:51:04
echo -n "1-3,7-9" | perl -ne 's/-/../g;$,=",";print eval $_'
https://stackoverflow.com/questions/41294406
复制相似问题