Often, I use parameter expansion on the command-line, such as

cp a.{ext1,ext2}

which is expands to

cp a.ext1 a.ext2

However, in many cases I do not use cp, but another tool, let's call it cat, and I would do some output redirection, like

cat a.ext1 > a.ext2

In my case a can vary, or be quite long, so I would like to be able to use some sort of brace expansion, that at least needs only one occurrence of a in the one-liner. How can I obtain that?

I am specifically using

$ bash --version
GNU bash, version 3.2.51(1)

but answers using other shells are also appreciated.

3 Answers 3


You can type:

$ cat very-long-filename.ext1Ctrl+WCtrl+Y>Ctrl+YBackspace2


$ cat very-long-filename.Ctrl+WCtrl+Yext1>Ctrl+Yext2

To really use brace expansion, note that:

cat a.ext1 > a.ext2

Can also be written:

cat > a.ext2 a.ext1

However you cannot do:

cat > a.ext{2,1}

However, you could do:

eval cat \> a.ext{2,1}

In zsh, you could also use an anonymous function:

(){cat $1 > $2} a.ext{1,2}


(){cat ${1}1 > ${1}2} a.ext
  • Interesting edit! With the cat > a.ext{2,1} I get an ambiguous redirect. Any idea why this is? Does { do anything special?
    – Bernhard
    Jul 3, 2014 at 10:36
  • @Bernhard You get that ambiguous redirect in bash any time you pass something that expands to more than one argument to a redirection operator. Same in a='a b'; echo > $a. With zsh, that would do some mult_ios (tee the output to both files) Jul 3, 2014 at 10:39
  • Does that imply that bash executes the redirect before the expansion? I would think that it expands first, an then operatres (basically like an alias would), but apparently my view is a bit naive.
    – Bernhard
    Jul 3, 2014 at 10:44
  • Funny detail: in zsh, cat > a.ext{2,1} other_file does function. But it outputs the content of other_file to both a.ext1 and a.ext2. I don't know how it manages to duplicate the redirection.
    – lgeorget
    Jul 4, 2014 at 12:45
  • @lgeorget, as I said, that's the multios feature whereby zsh implements a tee internally. Jul 4, 2014 at 12:47

What about:-

f=really-long-filename; cat "$f.ext1" > "$f.ext2"
  • That works, but is not really what I am looking for, as I would still have to retype the ${PR}
    – Bernhard
    Jul 3, 2014 at 8:38

Use a shell function

 xyx () { cat "$1".$2 > "$1".$3; }


xyz fie foo fum

expands to

cat fee.foo > fee.fum
  • Extensions .1 and .2 are typically not universal for me.
    – Bernhard
    Jul 3, 2014 at 11:54
  • Modified answer to take parameters.
    – Lenne
    Jul 4, 2014 at 12:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .