I have an operation using cut that I would like to assign result to a variable

var4=echo ztemp.xml |cut -f1 -d '.'

I get the error:

ztemp.xml is not a command

The value of var4 never gets assigned; I'm trying to assign it the output of:

echo ztemp.xml | cut -f1 -d '.'

How can I do that?


You'll want to modify your assignment to read:

var4="$(echo ztemp.xml | cut -f1 -d '.')"

The $(…) construct is known as command susbtitution.

  • 9
    @Vass: Better: var4=$(echo ztemp.xml | cut -f1 -d '.'). $(…) is mostly equivalent to ` `…` , except that quoting inside backquotes is peculiar (and in particular nesting backquotes is not recommended), whereas quoting inside $(…)` is unusually intuitive. Furthermore $(…) is more readable than ` `…` ` which is easily confused with '…' in many fonts. So if you're going to learn only one, learn $(…). – Gilles 'SO- stop being evil' Dec 6 '10 at 22:25
  • 1
    though the question explicitly states that the user wants to assign the output of a command to a variable, his intention in this case is very clearly to strip the file extension. since your answer has already been accepted, it would be most polite of you to update it to include tips from Dennis's answer below. – Josh McGee Jul 23 '13 at 19:26

Depending on the shell you're using, you can use Parameter Expansion. For instance in bash:

          Remove matching suffix pattern.  The word is expanded to produce
          a pattern just as in pathname expansion.  If the pattern matches
          a trailing portion of the expanded value of parameter, then  the
          result  of the expansion is the expanded value of parameter with
          the shortest matching pattern (the ``%'' case)  or  the  longest
          matching  pattern  (the ``%%'' case) deleted.  If parameter is @
          or *, the pattern removal operation is  applied  to  each  posi‐
          tional  parameter  in  turn,  and the expansion is the resultant
          list.  If parameter is an array variable subscripted with  @  or
          *,  the  pattern  removal operation is applied to each member of
          the array in turn, and the expansion is the resultant list.

In your case that would mean doing something like this:


Note that the character # behaves in a similar way on the prefix part of the string.

  • And use ${var4%%.*} to exactly match the original behavior for strings with multiple dots (e.g. foo.xml.gz). – Chris Johnsen Dec 7 '10 at 16:28

Ksh, Zsh and Bash all offer another, perhaps clearer syntax:

var4=$(echo ztemp.xml | cut -f1 -d '.')

The backticks (a.k.a. "grave accent") is unreadable in some fonts. The $(blahblah) syntax is a lot more obvious at least.

Note that you can pipe values into a read command in some shells:

ls -1 \*.\* | cut -f1 -d'.' | while read VAR4; do echo $VAR4; done
  • 2
    $() is specified by POSIX, so it's also available in Dash, Ash, and others. Piping into read won't work in Bash. – Dennis Williamson Dec 6 '10 at 22:07
  • @DennisWilliamson you can pipe into read, you just cant do it like that (if you want the variable to be accessible outside the loop): while read foo; do echo "$foo"; done < <(command here) – phemmer Jun 28 '12 at 22:06
  • @Patrick: That's not a pipe, it's redirection. It's process substitution redirected into done. – Dennis Williamson Jun 28 '12 at 22:35
  • 1
    @Patrick: No, they don't. They do have similarities, but they're different. – Dennis Williamson Jun 28 '12 at 22:42
  • 2
    the <() construct is essentially a reversed pipe; it's known as process substitution, and uses some other tricks. the noteworthy bit is that it creates a file descriptor (on my system, it tends to be /dev/fd/63) which stores the process's output. that's what makes the redirection work at all. <() itself just spits a filename out. < <() redirects the contents of it, just like < file. – Josh McGee Jul 23 '13 at 19:31

This is yet another way to assign a variable, good to use with some text editors that are unable to correctly highlight every intricate code you create.

read -r -d '' str < <(cat somefile.txt)
echo "${#str}"
echo "$str"
  • Your comment helped with an issue I had, thanks! – NetOperator Wibby Nov 29 '16 at 21:28
  • What can you do with read … < <(cat file.txt) that you can't do with read … < file.txt (which is more portable)? UUOC! – Scott Aug 12 '17 at 17:27
  • @Scott mmm, I learned that way <(), I think it is bash specific? – Aquarius Power Aug 12 '17 at 20:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.