Take the 2-minute tour ×
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.

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
1  
@Michael Mrozek you forgot to fix the spelling of "varialbe" when you edited ;-) –  Josh Dec 7 '10 at 14:19
    
@Josh Oh, didn't even notice. Thanks –  Michael Mrozek Dec 7 '10 at 15:06
    
@Michael I miss my SO editing privs on here :-) –  Josh Dec 7 '10 at 16:58
    
@Josh Yeah, editing is always the thing I miss having on SE sites –  Michael Mrozek Dec 7 '10 at 17:13

3 Answers 3

up vote 10 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
7  
@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:

   ${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.

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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