4 ms·
Why does this work? I always thought brackets were used to select a set of files. For example foo-bar-{baz,quux}.txt = foo-bar-baz.txt
by rambojazz 7y ago
Why does this work? I always thought brackets were used to select a set of files. For example
foo-bar-{baz,quux}.txt = foo-bar-baz.txt
foo-bar-quux.txt
- iokanuon 7y agoThat's exactly why that works, the shell expands it, so mv foo-bar-{baz,quux}.txt becomes mv foo-bar-baz.txt foo-bar-quux.txt
- deleted 7y ago[deleted]
- kelnos 7y agoDon't think of it as selecting files. It's just simple string substitution/expansion. "foo-bar-{baz,quux}.txt" just expands to "foo-bar-baz.txt" and "foo-bar-quux.txt", which are then passed to "mv" as separate arguments. The corresponding files need not exist, as this is a separate bit of functionality than file globbing.
- wahern 7y agoPathname expansion (i.e. globbing) can't even be used this way as POSIX requires matched names to be lexicographically sorted. That's the first thing that came to mind, before I remembered that brace expansion is a widely-supported extension not defined by POSIX.
- zenexer 7y agoBrace expansion doesn't fall under pathname expansion. There is no expectation that the resulting expansion will correspond to files. From `man bash`: > Expansion is performed on the command line after it has been split into words. There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion. That's not to say it's POSIX-compliant--I have no idea whether it is. But it definitely isn't grouped in with pathname expansion. bash does have an option to disable brace expansion, but it's not toggled by `--posix`, which leads me to believe it might be POSIX-compliant.
- wahern 7y ago> Brace expansion doesn't fall under pathname expansion. I thought that was implied in my post, but perhaps I should have made it explicit. > That's not to say it's POSIX-compliant--I have no idea whether it is I didn't know one way or another, but since you brought it up, it looks like it probably is not compliant. See, e.g., this argument that `echo {1,2}` must print '{1,2}' because POSIX doesn't require '{1,2}' to be quoted: https://www.austingroupbugs.net/view.php?id=1193 https://www.austingroupbugs.net/view.php?id=1193 Brace expansion is a nearly universally supported extension, though, so I doubt it's a real problem. And the above link proposes fixing the standard to make the extension compliant.
- carb 7y agoBraces just evaluate and expand. $ echo {A,B} A B $ echo {A,B}{C,D} AC AD BC BD $ echo {A,B}{C,D}{E,F} ACE ACF ADE ADF BCE BCF BDE BDF
- jraph 7y agoWow, I had not realized that one could compute Cartesian products using a shell.
- foobarian 7y agoOn the topic of things you didn't know the shell did: I found out about sequences recently and love them: $ echo {0..19} 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ echo {00..19} 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
- pkaye 7y agoLooks like it also works with single letters. $echo {A..D} A B C D
- smcameron 7y agoHmm, I'd always used the "seq" command for that... $ echo `seq 0 19` 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
- m463 7y agowow, genius! (the second doesn't work on older versions of bash, like macos)
- perlwle 7y agoPerl is very much like this too. $ perl -le 'print join(" ", "00".."20")' 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20
- tyingq 7y agoIt's also inside Perl as bsd_glob(). use File::Glob ':bsd_glob';
- 0xEFF 7y agoShell expansion into the two strings and the order you mentioned. These two strings are passed along the argument vector to the mv command.
- emmelaich 7y agoThe { .. } stuff expands regardless of whether it matches files. Unlike *, ? [a-z] ...