12

I was trying to concatenate text files in sub-folders and tried:

cat ./{mainfolder1,mainfolder2,mainfolder3}/{subfolder1}/book.txt > out$var

However this did not return anything. So, tried adding a non existing 'subfolder2'

cat ./{mainfolder1,mainfolder2,mainfolder3}/{subfolder1,subfolder2}/book.txt > out$var

And this time it did work out, concatenating the files successfully. Why does this happens?

Charles Duffy
  • 1,651
  • 15
  • 22
CDPF
  • 121
  • 4

3 Answers3

22

By definition, brace expansion in GNU Bash requires either a sequence expression or a series of comma-separated values:

Patterns to be brace expanded take the form of an optional preamble, followed by either a series of comma-separated strings or a sequence expression between a pair of braces, followed by an optional postscript.

You can read the manual for details.

A few simple samples:

echo {subfolder1}
{subfolder1}

echo {subfolder1,subfolder2}
subfolder1 subfolder2

echo subfolder{1}
subfolder{1}

echo subfolder{1..2}
subfolder1 subfolder2
Arthur Hess
  • 388
  • 1
  • 5
21

{subfolder1} evaluates to {subfolder1}, since there are no alternatives. Use subfolder1 instead.

David Foerster
  • 1,505
  • 1
  • 11
  • 18
Ignacio Vazquez-Abrams
  • 44,857
  • 7
  • 93
  • 100
1

Braces will only expand if they have coma separated strings, for e.g. {abc,def} or range, for e.g. {a..e} specified between them.

In your case you can just write subfolder1 without enclosing it in braces as there is no need for that

cat ./{mainfolder1,mainfolder2,mainfolder3}/subfolder1/book.txt > out$var
Neo_Returns
  • 529
  • 3
  • 14
  • Unfortunately, `/path/{a,}/filename` expands to the _two_ strings `/path/a/filename` and `/path//filename`, which may be unwanted. – Kusalananda May 19 '18 at 17:02
  • thanks @Kusalananda for rectifying me, yes bash will provide a warning saing "ambiguous redirect" – Neo_Returns May 19 '18 at 17:10
  • No, you get `ambiguous redirect` if you try to redirect into a file given by an unquoted variable that has no value, e.g. `echo 'hello' >$idontexist`. – Kusalananda May 19 '18 at 17:14
  • 1
    ...or if the filename in the redirection gets expanded to multiple words. Like `> *.txt` with multiple `.txt` files, or `> $file` if `$file` contains whitespace. But of course there's nothing ambiguous in giving `cat` multiple arguments – ilkkachu May 20 '18 at 08:33