在括号扩展期间如何抑制生成的参数之间的间隔?


8

我使用以下命令创建了要测试的URL列表:

echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

不幸的是,urls.txt每个URL后面都有一个空格(当然,第一个除外)。我了解为什么会发生这种情况,并且我意识到我可以通过在sed表达式中使用管道将其剥离,但是我想知道是否有一种抑制它的方法。(这看起来很愚蠢和古怪,但这与很多人不喜欢“虐待猫”的偏好没有什么不同。)

我尝试使用双引号来抑制单词拆分,但是那也抑制了括号的扩展,所以这是不可行的。

我尝试将IFS更改为空字符串,但也没有用:

IFS='' echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

也没有将其更改为换行符:

IFS='\n' echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

您正在使用bash还是zsh?
Braiam 2014年

目前,我正在使用bash(我在工作),但是在我自己的笔记本电脑上,我使用zsh。我原本希望大括号扩展在这两者中可以相同地工作,但事实并非如此。
iconoclast

在这种情况下,Gnouc答案将与不同的shell最兼容。
Braiam

理查德的答案会同样兼容吗?(它还具有更简单的优点,因此下次我不想使用它时,我不必停下来思考一下。)另一方面,Gnouc的回答也很好。我想我从格伦·杰克逊的答案中学到了最多的东西。Leiaz的答案似乎最简单,最优雅,但是当然只有zsh。
iconoclast 2014年

Answers:


8

您可以将大括号扩展存储在数组中,然后以您选择的方式输出:

urls=( localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload} )

然后

printf "%s\n" "${urls[@]}"

要么

(IFS=$'\n'; echo "${urls[*]}")

回显示例看起来很奇怪,因为:

  1. 它在子外壳程序(括号)中运行,因此我不会更改我的IFS当前值。
  2. IFS需要在单独的命令中定义:
    • 这是行不通的:IFS=$'\n' echo "${urls[*]}"因为在新的env变量生效之前,变量已展开
    • 开始扩展变量之前,需要设置IFS 。

另外,请注意所使用的解引用数组索引之间的细微差别:

  • [@] 在printf示例中,将数组扩展为单个单词
  • [*] 在echo示例中,将数组扩展为单个单词,其元素由IFS的第一个字符分隔

这是一个艰难的决定,但我选择这个答案是因为(1)(AFAIK)似乎是最接近既定目标的压制,而不是仅仅消除空格,而且(2)我从中学到了很多(说出我的问题的目标)。
iconoclast 2014年

16

使用printf内置的:

$ printf %s\\n localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}
localhost:8080/reports/promos/130
localhost:8080/reports/promos/130.pdf
localhost:8080/reports/promos/130.xls
localhost:8080/reports/promos/130.xlsx
localhost:8080/reports/promos/130.csv
localhost:8080/reports/promos/130.preload
localhost:8080/reports/promos/130-unburdened
localhost:8080/reports/promos/130-unburdened.pdf
localhost:8080/reports/promos/130-unburdened.xls
localhost:8080/reports/promos/130-unburdened.xlsx
localhost:8080/reports/promos/130-unburdened.csv
localhost:8080/reports/promos/130-unburdened.preload
....

6

这被标记为zsh,所以我建议使用zsh内置print

print -l localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}

-l 在单独的行上打印参数。


+1谢谢-很高兴知道!我在zsh上时会用到它。我标记它的原因仅仅是因为我同时使用了两者,并且都支持花括号扩展。(我不知道是否有其他人这样做,但是我发现ksh令人困惑,所以我不去做。)
iconoclast 2014年

3

问题是大括号扩展增加了空间,而echo增加了换行符。因此,使用单一职责原则,应单独处理换行符。

echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload} | tr " " "\n"

我认为这是最简单,最实用的方法
iconoclast

不,花括号扩展未添加空间,而是为创建了多个参数echo。那echo就是打印用空格分隔的参数。
斯特凡Chazelas

我猜发生问题是因为echo用空格分隔参数,并且每个空格之前还添加了换行符,而不是替换了空格(这会更明智)。从内存中,xargs有一个与此已知的问题非常相似的已知问题(尤其是该-0选项)
语法错误
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.