Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This question already has an answer here:

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?

share|improve this question

marked as duplicate by terdon Jun 2 '15 at 9:02

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

up vote 18 down vote accepted

You'll want to modify your assignment to read:

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

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

share|improve this answer
@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 Dec 6 '10 at 22:25
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.

share|improve this answer
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
share|improve this answer
$() 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) – Patrick 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
@Patrick: No, they don't. They do have similarities, but they're different. – Dennis Williamson Jun 28 '12 at 22:42
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"
share|improve this answer

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