Storing output of command in shell variable

138,746

Solution 1

You'll want to modify your assignment to read:

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

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

Solution 2

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

   ${parameter%word}
   ${parameter%%word}
          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:

var4=ztemp.xml
var4=${var4%.*}

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

Solution 3

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

Solution 4

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:
138,746

Related videos on Youtube

Vass
Author by

Vass

Updated on September 17, 2022

Comments

  • Vass
    Vass over 1 year

    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?

  • Brian Rasmussen
    Brian Rasmussen over 13 years
    $() is specified by POSIX, so it's also available in Dash, Ash, and others. Piping into read won't work in Bash.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    @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 $(…).
  • Chris Johnsen
    Chris Johnsen over 13 years
    And use ${var4%%.*} to exactly match the original behavior for strings with multiple dots (e.g. foo.xml.gz).
  • Brian Rasmussen
    Brian Rasmussen almost 12 years
    @Patrick: That's not a pipe, it's redirection. It's process substitution redirected into done.
  • phemmer
    phemmer almost 12 years
    @DennisWilliamson pipes are redirection. They do the same thing
  • Brian Rasmussen
    Brian Rasmussen almost 12 years
    @Patrick: No, they don't. They do have similarities, but they're different.
  • phemmer
    phemmer almost 12 years
    @DennisWilliamson Yes they are. Seriously, just try it. Run these 2 commands cat < <(sleep 10) and sleep 10 | cat, and to an lsof on the cat and sleep, you wont see any differences between the two.
  • Brian Rasmussen
    Brian Rasmussen almost 12 years
    Piping sleep to cat is nonsensical, but perhaps useful for some types of testing. If pipes and redirection were the same, then piping into while wouldn't set up a subshell. Also, process substitution uses named pipes or /dev/fd. So, now try your tests, but add & echo $! at the end and do ls -l /proc/PID/fd in another teminal, substituting the PID that was echoed. Seriously, just try it.
  • Brian Rasmussen
    Brian Rasmussen almost 12 years
    I forgot to say @Patrick in that last comment.
  • Josh McGee
    Josh McGee almost 11 years
    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
    Josh McGee almost 11 years
    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.
  • NetOperator Wibby
    NetOperator Wibby over 7 years
    Your comment helped with an issue I had, thanks!
  • Scott - Слава Україні
    Scott - Слава Україні over 6 years
    What can you do with read … < <(cat file.txt) that you can't do with read … < file.txt (which is more portable)? UUOC!
  • Aquarius Power
    Aquarius Power over 6 years
    @Scott mmm, I learned that way <(), I think it is bash specific?