Bash

如何在沒有組合爆炸的情況下進行多個大括號擴展?

  • September 3, 2013

我經常在命令行上使用大括號擴展,因為它很方便。

例子

{foo,bar}

擴展為:

foo bar

多括號展開也展開,例如:

{foo,bar}Q{foo,bar}

將擴展為:

fooQfoo fooQbar barQfoo barQbar

這是按順序使用大括號擴展的預期行為。

我的問題

現在,我希望任何大括號擴展(或其他簡短的命令行技巧)的輸出為:

fooQfoo barQbar

注意:我正在使用bash 3.2

我不知道如何只使用花括號來完成這項工作。我也看不到實現這一目標的方法,所以除非有人比我更聰明,否則我會說這是不可能的。

作為備選

樣本數據

$ tree
.
|-- dir1
|   |-- file1
|   `-- file2
`-- dir2
   |-- file1
   `-- file2

例子

$ seq 2 | xargs -i{} echo dir{}/file{}
dir1/file1
dir2/file2

這可以放入這樣的命令中:

$ echo $(seq 2 | xargs -i{} echo dir{}/file{})
dir1/file1 dir2/file2

或這個:

$ ls $(seq 2 | xargs -i{} echo dir{}/file{})
dir1/file1  dir2/file2

或這個:

$ ls -l $(seq 2 | xargs -i{} echo dir{}/file{})
-rw-rw-r-- 1 saml saml 0 Sep  2 03:18 dir1/file1
-rw-rw-r-- 1 saml saml 0 Sep  2 03:31 dir2/file2

為什麼花括號不能這樣做

如果您查看原始範例:

{foo,bar}Q{foo,bar}

其擴展方式如下:

fooQfoo fooQbar barQfoo barQbar

擴展它的機制稱為笛卡爾積

例如:

$ echo {A,B}{X,Y,Z}
AX AY AZ BX BY BZ

或這個:

$ echo {M,N}-{A,B}{X,Y,Z}
M-AX M-AY M-AZ M-BX M-BY M-BZ N-AX N-AY N-AZ N-BX N-BY N-BZ

沒有辦法創建一個笛卡爾積,它會導致:

fooQfoo barQbar

你唯一的選擇是要麼訴諸這樣的詭計:

$ echo dir{1,2}/file{2,1}
dir1/file2 dir1/file1 dir2/file2 dir2/file1

然後將其放入 Bash 數組中:

$ a=(dir{1,2}/file{2,1})
$ echo ${a[@]:1:2}
dir1/file1 dir2/file2

另一種選擇是某種“其他方法”,例如我之前在上面討論過的方法(使用xargs)。

參考

我同意slm;我從未見過僅通過大括號擴展來做到這一點的方法。

但是,使用問題中的範例,我認為獲得所需輸出的最簡單方法是使用循環,而不是大括號擴展和額外的後處理:

$ echo $(for X in foo bar;do echo ${X}Q${X};done)
fooQfoo barQbar

引用自:https://unix.stackexchange.com/questions/89113