News for hackers. Stuff that matters.
Re:Renaming files with mv without typing the name two times by rambojazz on Monday April 13, 2020 @05:32PM (#22860305)
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
Re:Renaming files with mv without typing the name two times by kelnos on Monday April 13, 2020 @05:35PM (#22860342)
Don'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.
Re:Renaming files with mv without typing the name two times by wahern on Monday April 13, 2020 @06:01PM (#22860653)
Pathname 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.
Re:Renaming files with mv without typing the name two times by zenexer on Monday April 13, 2020 @06:28PM (#22860896)
Brace 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.

Re:Renaming files with mv without typing the name two times by wahern on Monday April 13, 2020 @06:38PM (#22860962)
> 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

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.

Re:Renaming files with mv without typing the name two times by carb on Monday April 13, 2020 @05:35PM (#22860346)
Braces 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
Re:Renaming files with mv without typing the name two times by jraph on Monday April 13, 2020 @06:07PM (#22860722)
Wow, I had not realized that one could compute Cartesian products using a shell.
Re:Renaming files with mv without typing the name two times by foobarian on Monday April 13, 2020 @06:21PM (#22860840)
On 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

Re:Renaming files with mv without typing the name two times by pkaye on Monday April 13, 2020 @06:29PM (#22860904)
Looks like it also works with single letters.

$echo {A..D}

A B C D

Re:Renaming files with mv without typing the name two times by smcameron on Monday April 13, 2020 @09:12PM (#22861860)
Hmm, 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

Re:Renaming files with mv without typing the name two times by perlwle on Tuesday April 14, 2020 @10:48AM (#22866657)
Perl 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

Re:Renaming files with mv without typing the name two times by m463 on Tuesday April 14, 2020 @08:14AM (#22864927)
wow, genius!

(the second doesn't work on older versions of bash, like macos)

Re:Renaming files with mv without typing the name two times by mehrdadn on Monday April 13, 2020 @09:07PM (#22861836)
Well, using Bash. A lot of these tricks aren't portable so you'll have fun when your scripts break on e.g. Dash (Ubuntu).
Re:Renaming files with mv without typing the name two times by jraph on Tuesday April 14, 2020 @02:03AM (#22863144)
Also works on zsh and fish, though fish does not enumerate in the same order. Indeed does not work on sh.

Thanks for the heads up.

Too bad it's not portable, but I guess this is mainly useful in an interactive shell.

I mostly use #!/usr/bin/env sh, so my scripts will remain free of shell Cartesian products and other brace expansions.

Re:Renaming files with mv without typing the name two times by tyingq on Monday April 13, 2020 @06:21PM (#22860841)
It's also inside Perl as bsd_glob().

  use File::Glob ':bsd_glob';
Re:Renaming files with mv without typing the name two times by iokanuon on Monday April 13, 2020 @05:33PM (#22860321)
That'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
Re:Renaming files with mv without typing the name two times by 0xEFF on Monday April 13, 2020 @05:51PM (#22860535)
Shell expansion into the two strings and the order you mentioned. These two strings are passed along the argument vector to the mv command.
Re:Renaming files with mv without typing the name two times by emmelaich on Monday April 13, 2020 @06:42PM (#22860993)
The { .. } stuff expands regardless of whether it matches files.

Unlike *, ? [a-z] ...